From 731d754d5dd5ad5e4c8bd6f9791a763d4f2457f2 Mon Sep 17 00:00:00 2001 From: extio-de Date: Sat, 31 Jan 2026 13:57:35 +0100 Subject: [PATCH] feat(renderer): add ASCII and Terminal themes with corresponding pattern renderers and font support --- data/renderer/GoogleSansCode-Regular.ttf | Bin 0 -> 55032 bytes data/renderer/Inconsolata-Regular.ttf | Bin 0 -> 101748 bytes .../renderer/g2d/G2DAutoConfiguration.java | 26 ++ .../g2d/theme/AsciiPatternRenderer.java | 198 +++++++++++++++ .../g2d/theme/AsciiThemeFactoryBean.java | 37 +++ .../g2d/theme/TerminalPatternRenderer.java | 235 ++++++++++++++++++ .../g2d/theme/TerminalThemeFactoryBean.java | 37 +++ 7 files changed, 533 insertions(+) create mode 100644 data/renderer/GoogleSansCode-Regular.ttf create mode 100644 data/renderer/Inconsolata-Regular.ttf create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiPatternRenderer.java create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiThemeFactoryBean.java create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalPatternRenderer.java create mode 100644 src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalThemeFactoryBean.java diff --git a/data/renderer/GoogleSansCode-Regular.ttf b/data/renderer/GoogleSansCode-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5c520addd99ed38dbf4bfaef718c460c526d67a6 GIT binary patch literal 55032 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 ko67UA asciiTheme() { + return new AsciiThemeFactoryBean(); + } + + @Bean + FactoryBean terminalTheme() { + return new TerminalThemeFactoryBean(); + } + @Bean @ConditionalOnMissingBean G2DDrawBackground g2dDrawBackground() { @@ -275,4 +289,16 @@ public class G2DAutoConfiguration { return new VintagePatternRenderer(); } + @Bean + @ConditionalOnMissingBean + AsciiPatternRenderer asciiPatternRenderer() { + return new AsciiPatternRenderer(); + } + + @Bean + @ConditionalOnMissingBean + TerminalPatternRenderer terminalPatternRenderer() { + return new TerminalPatternRenderer(); + } + } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiPatternRenderer.java new file mode 100644 index 0000000..4e1afc1 --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiPatternRenderer.java @@ -0,0 +1,198 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont; +import de.extio.game_engine.spatial2.model.CoordI2; + +public class AsciiPatternRenderer 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) { + g2d.setColor(color); + + // Use simple ASCII characters for borders + final int fontSize = Math.max(8, strength * 4); // Scale font size with strength + + // Get character dimensions + final var horizDim = G2DDrawFont.getTextDimensions("-", g2d, fontSize, 1.0); + final var vertDim = G2DDrawFont.getTextDimensions("|", g2d, fontSize, 1.0); + final var cornerDim = G2DDrawFont.getTextDimensions("+", g2d, fontSize, 1.0); + + final int charWidth = Math.max(1, (int)horizDim.getX()); + final int charHeight = Math.max(1, (int)cornerDim.getY()); + + final int horizChars = Math.max(0, (width - 2 * charWidth) / charWidth); + final int vertChars = Math.max(0, (height - 2 * charHeight) / charHeight); + + final int totalWidth = (horizChars + 2) * charWidth; + final int totalHeight = (vertChars + 2) * charHeight; + final int offsetX = x + Math.max(0, (width - totalWidth) / 2); + final int offsetY = y + Math.max(0, (height - totalHeight) / 2); + + // Top border + G2DDrawFont.renderText(g2d, cornerDim, 1.0, offsetX, offsetY, fontSize, "+"); + for (int i = 0; i < horizChars; i++) { + G2DDrawFont.renderText(g2d, horizDim, 1.0, offsetX + charWidth + i * charWidth, offsetY, fontSize, "-"); + } + G2DDrawFont.renderText(g2d, cornerDim, 1.0, offsetX + charWidth + horizChars * charWidth, offsetY, fontSize, "+"); + + // Bottom border + G2DDrawFont.renderText(g2d, cornerDim, 1.0, offsetX, offsetY + charHeight + vertChars * charHeight, fontSize, "+"); + for (int i = 0; i < horizChars; i++) { + G2DDrawFont.renderText(g2d, horizDim, 1.0, offsetX + charWidth + i * charWidth, offsetY + (int)(charHeight * 1.5) + vertChars * charHeight, fontSize, "-"); + } + G2DDrawFont.renderText(g2d, cornerDim, 1.0, offsetX + charWidth + horizChars * charWidth, offsetY + charHeight + vertChars * charHeight, fontSize, "+"); + + // Left and right borders + for (int i = 0; i < vertChars; i++) { + G2DDrawFont.renderText(g2d, vertDim, 1.0, offsetX, offsetY + charHeight + i * charHeight, fontSize, "|"); + G2DDrawFont.renderText(g2d, vertDim, 1.0, offsetX + charWidth + horizChars * charWidth, offsetY + charHeight + i * charHeight, fontSize, "|"); + } + } + + @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 ? 2 : 1), (int) ((thickBorder ? 3 : 2) * scaleFactor)); + final var s2 = s * 2; + + final var bg = new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), 240); + this.drawDecorativeBorderFilled(g2d, x + s, y + s, width - s2, height - s2, s, innerBorderColor, bg); + this.drawDecorativeBorder(g2d, x, y, width, height, s, outerBorderColor); + } + + @Override + public void drawCloseButton(final Graphics2D g2d, final int width, final int height, final boolean enabled, final boolean pressed, final boolean hovered, final boolean toggled, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final var highlight = (hovered || toggled); + + Color bgColor = backgroundColor; + if (bgColor == null) { + bgColor = theme.getBorderInner().toColor(); + } + if (highlight) { + bgColor = theme.getBackgroundNormal().toColor(); + } + if (pressed) { + bgColor = theme.getSelectionPrimary().toColor(); + } + + g2d.setColor(bgColor); + g2d.fillRect(0, 0, width, height); + + final var s = Math.max(1, (int) (1 * scaleFactor)); + this.drawDecorativeBorder(g2d, 0, 0, width, height, s, theme.getBorderOuter().toColor()); + + if (!enabled) { + return; + } + + final Color textColor; + if (pressed) { + textColor = theme.getTextNormal().toColor(); + } + else if (highlight) { + textColor = theme.getSelectionSecondary().toColor(); + } + else { + textColor = theme.getTextDisabled().toColor(); + } + g2d.setColor(textColor); + + final var fontSize = (int) (12 * scaleFactor); + final var textDim = G2DDrawFont.getTextDimensions("X", g2d, 12, scaleFactor); + G2DDrawFont.renderText(g2d, textDim, 1.0, ((width - textDim.getX()) / 2), ((height - textDim.getY()) / 2), fontSize, "X"); + } + + private java.awt.image.BufferedImage patternCache; + + private java.awt.image.BufferedImage getPatternCache() { + if (this.patternCache == null) { + final int spacing = 40; + this.patternCache = new BufferedImage(spacing, spacing, java.awt.image.BufferedImage.TYPE_INT_ARGB); + final Graphics2D g2d = this.patternCache.createGraphics(); + + g2d.setBackground(new Color(0, 0, 0, 0)); + g2d.clearRect(0, 0, spacing, spacing); + + // Simple ASCII-like pattern - just dots + g2d.setColor(new Color(0, 255, 0, 30)); + g2d.fillRect(spacing / 2 - 1, spacing / 2 - 1, 2, 2); + + g2d.dispose(); + } + return this.patternCache; + } + + @Override + public void drawBackgroundPattern(final Graphics2D g2d, final CoordI2 offset, final CoordI2 viewPort) { + final var cache = this.getPatternCache(); + final int spacing = cache.getWidth(); + + final int offX = Math.floorMod(offset.getX(), spacing); + final int offY = Math.floorMod(offset.getY(), spacing); + + for (int x = -spacing; x < viewPort.getX() + spacing; x += spacing) { + for (int y = -spacing; y < viewPort.getY() + spacing; y += spacing) { + g2d.drawImage(cache, x + offX, y + offY, null); + } + } + } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final boolean pressed, final boolean hovered, final boolean toggled, final Color backgroundColor, final double scaleFactor, final Theme theme) { + Color bgColor; + if (backgroundColor == null) { + final var baseColor = !toggled ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + float b = baseColor.getBrightness(); + + if (pressed) { + b += theme.getPressedBrightnessAdjustment(); + } + else if (hovered) { + b += theme.getHoverBrightnessAdjustment(); + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + bgColor = Color.getHSBColor(baseColor.getHue(), baseColor.getSaturation(), b); + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + + float b = !toggled ? 0.25F : 0.45F; + if (pressed) { + b += theme.getPressedBrightnessAdjustment(); + } + else if (hovered) { + b += theme.getHoverBrightnessAdjustment(); + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + bgColor = Color.getHSBColor(hsb[0], hsb[1], b); + } + + if (!enabled) { + final var hsb = Color.RGBtoHSB(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), null); + bgColor = Color.getHSBColor(hsb[0], Math.min(1.0f, hsb[1] * 0.1f), Math.min(1.0f, hsb[2] * 0.5f)); + } + + // Simple flat fill, no gradient for ASCII style + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + // Simple border + final var borderStrength = Math.max(1, (int) (1 * scaleFactor)); + final var borderColor = hovered ? theme.getSelectionPrimary().toColor() : theme.getBorderOuter().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } +} \ No newline at end of file diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiThemeFactoryBean.java new file mode 100644 index 0000000..99ba425 --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/AsciiThemeFactoryBean.java @@ -0,0 +1,37 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import org.springframework.beans.factory.FactoryBean; + +public class AsciiThemeFactoryBean implements FactoryBean { + + @Override + public Theme getObject() { + return Theme.builder() + .name("ASCII") + .font("Inconsolata-Regular.ttf") + .patternRendererName("asciiPatternRenderer") + .borderOuter(new HSBColor(0.00f, 0.00f, 0.30f)) + .borderInner(new HSBColor(0.00f, 0.00f, 0.50f)) + .borderInnerDisabled(new HSBColor(0.00f, 0.00f, 0.15f)) + .backgroundNormal(new HSBColor(0.00f, 0.00f, 0.10f)) + .backgroundSelected(new HSBColor(0.50f, 0.50f, 0.30f)) + .textNormal(new HSBColor(0.33f, 1.00f, 0.80f)) + .textDisabled(new HSBColor(0.33f, 0.50f, 0.50f)) + .selectionPrimary(new HSBColor(0.50f, 0.50f, 0.50f)) + .selectionSecondary(new HSBColor(0.50f, 0.70f, 0.70f)) + .windowBackground(new HSBColor(0.00f, 0.00f, 0.05f)) + .hoverBrightnessAdjustment(0.15f) + .pressedBrightnessAdjustment(0.30f) + .build(); + } + + @Override + public Class getObjectType() { + return Theme.class; + } + + @Override + public boolean isSingleton() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalPatternRenderer.java new file mode 100644 index 0000000..b72d20e --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalPatternRenderer.java @@ -0,0 +1,235 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; + +import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont; +import de.extio.game_engine.spatial2.model.CoordI2; + +public class TerminalPatternRenderer implements PatternRenderer { + + private BufferedImage patternCache; + + @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) { + final var s = Math.max(1, strength); + final var tick = Math.max(1, s * 2); + final var glyph = Math.max(1, s); + + g2d.setColor(color); + final var step = glyph * 4; + final var seg = glyph * 2; + + for (int gx = x; gx <= x + width - seg; gx += step) { + g2d.fillRect(gx, y, seg, s); + g2d.fillRect(gx + glyph, y + s, glyph, s); + g2d.fillRect(gx, y + height - s, seg, s); + g2d.fillRect(gx + glyph, y + height - s - s, glyph, s); + } + + for (int gy = y; gy <= y + height - seg; gy += step) { + g2d.fillRect(x, gy, s, seg); + g2d.fillRect(x + s, gy + glyph, s, glyph); + g2d.fillRect(x + width - s, gy, s, seg); + g2d.fillRect(x + width - s - s, gy + glyph, s, glyph); + } + + g2d.fillRect(x + s, y + s, tick, s); + g2d.fillRect(x + width - s - tick, y + s, tick, s); + g2d.fillRect(x + s, y + height - s - s, tick, s); + g2d.fillRect(x + width - s - tick, y + height - s - s, tick, s); + + final var innerLeft = x + s + glyph * 3; + final var innerRight = x + width - s - glyph * 3; + final var innerTop = y + s + glyph * 2; + final var innerBottom = y + height - s - glyph * 2; + + for (int gx = innerLeft; gx <= innerRight; gx += glyph * 6) { + g2d.fillRect(gx, y + s, glyph * 2, glyph); + g2d.fillRect(gx + glyph * 3, y + s, glyph, glyph); + g2d.fillRect(gx, y + height - s - glyph, glyph * 2, glyph); + g2d.fillRect(gx + glyph * 3, y + height - s - glyph, glyph, glyph); + } + + for (int gy = innerTop; gy <= innerBottom; gy += glyph * 6) { + g2d.fillRect(x + s, gy, glyph, glyph * 2); + g2d.fillRect(x + s, gy + glyph * 3, glyph, glyph); + g2d.fillRect(x + width - s - glyph, gy, glyph, glyph * 2); + g2d.fillRect(x + width - s - glyph, gy + glyph * 3, glyph, glyph); + } + } + + @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 ? 2 : 1), (int) ((thickBorder ? 3 : 2) * scaleFactor)); + final var s2 = s * 2; + + final var bg = new Color(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), 230); + this.drawDecorativeBorderFilled(g2d, x + s, y + s, width - s2, height - s2, s, innerBorderColor, bg); + this.drawDecorativeBorder(g2d, x, y, width, height, s, outerBorderColor); + } + + @Override + public void drawCloseButton(final Graphics2D g2d, final int width, final int height, final boolean enabled, final boolean pressed, final boolean hovered, final boolean toggled, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final var highlight = (hovered || toggled); + + Color bgColor = backgroundColor; + if (bgColor == null) { + bgColor = theme.getBorderInner().toColor(); + } + if (highlight) { + bgColor = theme.getBackgroundNormal().toColor(); + } + if (pressed) { + bgColor = theme.getSelectionPrimary().toColor(); + } + + g2d.setColor(bgColor); + g2d.fillRect(0, 0, width, height); + + final var s = Math.max(1, (int) (1 * scaleFactor)); + this.drawDecorativeBorder(g2d, 0, 0, width, height, s, theme.getBorderOuter().toColor()); + + if (!enabled) { + return; + } + + final Color textColor; + if (pressed) { + textColor = theme.getTextNormal().toColor(); + } + else if (highlight) { + textColor = theme.getSelectionSecondary().toColor(); + } + else { + textColor = theme.getTextDisabled().toColor(); + } + g2d.setColor(textColor); + + final var fontSize = (int) (12 * scaleFactor); + final var textDim = G2DDrawFont.getTextDimensions("X", g2d, 12, scaleFactor); + G2DDrawFont.renderText(g2d, textDim, 1.0, ((width - textDim.getX()) / 2), ((height - textDim.getY()) / 2), fontSize, "X"); + } + + private BufferedImage getPatternCache() { + if (this.patternCache == null) { + final int spacing = 56; + this.patternCache = new BufferedImage(spacing, spacing, BufferedImage.TYPE_INT_ARGB); + final Graphics2D g2d = this.patternCache.createGraphics(); + + g2d.setBackground(new Color(0, 0, 0, 0)); + g2d.clearRect(0, 0, spacing, spacing); + + g2d.setColor(new Color(255, 225, 170, 14)); + for (int y = 0; y < spacing; y += 7) { + g2d.fillRect(0, y, spacing, 1); + } + + final var soft = new Color(255, 210, 140, 26); + final var strong = new Color(255, 205, 120, 36); + + final int cx = spacing / 2; + final int cy = spacing / 2; + + g2d.setColor(soft); + g2d.fillRect(cx - 10, cy - 10, 2, 2); + g2d.fillRect(cx + 8, cy - 10, 2, 2); + g2d.fillRect(cx - 10, cy + 8, 2, 2); + g2d.fillRect(cx + 8, cy + 8, 2, 2); + + g2d.setColor(strong); + g2d.fillRect(cx - 3, cy - 6, 1, 12); + g2d.fillRect(cx - 6, cy - 3, 12, 1); + + g2d.setColor(soft); + g2d.fillRect(cx + 14, cy + 14, 3, 1); + g2d.fillRect(cx + 16, cy + 12, 1, 3); + + g2d.fillRect(cx - 18, cy + 6, 6, 1); + g2d.fillRect(cx - 18, cy + 6, 1, 4); + g2d.fillRect(cx - 13, cy + 6, 1, 4); + g2d.fillRect(cx - 16, cy + 9, 3, 1); + + g2d.fillRect(cx + 2, cy - 16, 6, 1); + g2d.fillRect(cx + 7, cy - 16, 1, 4); + g2d.dispose(); + } + return this.patternCache; + } + + @Override + public void drawBackgroundPattern(final Graphics2D g2d, final CoordI2 offset, final CoordI2 viewPort) { + final var cache = this.getPatternCache(); + final int spacing = cache.getWidth(); + + final int offX = Math.floorMod(offset.getX(), spacing); + final int offY = Math.floorMod(offset.getY(), spacing); + + for (int x = -spacing; x < viewPort.getX() + spacing; x += spacing) { + for (int y = -spacing; y < viewPort.getY() + spacing; y += spacing) { + g2d.drawImage(cache, x + offX, y + offY, null); + } + } + } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final boolean pressed, final boolean hovered, final boolean toggled, final Color backgroundColor, final double scaleFactor, final Theme theme) { + Color bgColor; + if (backgroundColor == null) { + final var baseColor = !toggled ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + float b = baseColor.getBrightness(); + + if (pressed) { + b += theme.getPressedBrightnessAdjustment(); + } + else if (hovered) { + b += theme.getHoverBrightnessAdjustment(); + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + bgColor = Color.getHSBColor(baseColor.getHue(), baseColor.getSaturation(), b); + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + + float b = !toggled ? 0.20F : 0.40F; + if (pressed) { + b += theme.getPressedBrightnessAdjustment(); + } + else if (hovered) { + b += theme.getHoverBrightnessAdjustment(); + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + bgColor = Color.getHSBColor(hsb[0], hsb[1], b); + } + + if (!enabled) { + final var hsb = Color.RGBtoHSB(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), null); + bgColor = Color.getHSBColor(hsb[0], Math.min(1.0f, hsb[1] * 0.15f), Math.min(1.0f, hsb[2] * 0.45f)); + } + + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(1, (int) (1 * scaleFactor)); + final var outer = hovered || toggled ? theme.getSelectionPrimary().toColor() : theme.getBorderOuter().toColor(); + final var inner = enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, outer); + + final var inset = Math.max(1, borderStrength); + if (width > inset * 3 && height > inset * 3) { + this.drawDecorativeBorder(g2d, x + inset, y + inset, width - inset * 2, height - inset * 2, Math.max(1, borderStrength), inner); + } + } +} diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalThemeFactoryBean.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalThemeFactoryBean.java new file mode 100644 index 0000000..ef59231 --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/TerminalThemeFactoryBean.java @@ -0,0 +1,37 @@ +package de.extio.game_engine.renderer.g2d.theme; + +import org.springframework.beans.factory.FactoryBean; + +public class TerminalThemeFactoryBean implements FactoryBean { + + @Override + public Theme getObject() { + return Theme.builder() + .name("Terminal") + .font("GoogleSansCode-Regular.ttf") + .patternRendererName("terminalPatternRenderer") + .borderOuter(new HSBColor(0.10f, 0.45f, 0.45f)) + .borderInner(new HSBColor(0.10f, 0.30f, 0.70f)) + .borderInnerDisabled(new HSBColor(0.10f, 0.15f, 0.25f)) + .backgroundNormal(new HSBColor(0.08f, 0.65f, 0.12f)) + .backgroundSelected(new HSBColor(0.12f, 0.70f, 0.35f)) + .textNormal(new HSBColor(0.12f, 0.85f, 0.95f)) + .textDisabled(new HSBColor(0.12f, 0.45f, 0.60f)) + .selectionPrimary(new HSBColor(0.10f, 0.75f, 0.55f)) + .selectionSecondary(new HSBColor(0.14f, 0.80f, 0.85f)) + .windowBackground(new HSBColor(0.08f, 0.55f, 0.08f)) + .hoverBrightnessAdjustment(0.18f) + .pressedBrightnessAdjustment(0.32f) + .build(); + } + + @Override + public Class getObjectType() { + return Theme.class; + } + + @Override + public boolean isSingleton() { + return true; + } +}