From 8fa370bcbf3afa96c89d91652a15156b48365510 Mon Sep 17 00:00:00 2001 From: extio-de Date: Mon, 29 Dec 2025 22:45:27 +0100 Subject: [PATCH] feat(renderer): implement drawButton method for pattern renderers to enhance button styling --- .../g2d/control/components/CustomButton.java | 58 ++---------------- .../g2d/control/components/CustomSwitch.java | 44 +------------- .../g2d/theme/BevelPatternRenderer.java | 59 +++++++++++++++++++ .../g2d/theme/BlueprintPatternRenderer.java | 53 +++++++++++++++++ .../g2d/theme/DreamPatternRenderer.java | 55 +++++++++++++++++ .../g2d/theme/FantasyPatternRenderer.java | 52 ++++++++++++++++ .../g2d/theme/MetroPatternRenderer.java | 52 ++++++++++++++++ .../g2d/theme/ModernPatternRenderer.java | 52 ++++++++++++++++ .../renderer/g2d/theme/PatternRenderer.java | 16 +++++ .../g2d/theme/SpacecraftPatternRenderer.java | 52 ++++++++++++++++ .../g2d/theme/UrbanPatternRenderer.java | 52 ++++++++++++++++ .../g2d/theme/VintagePatternRenderer.java | 53 +++++++++++++++++ 12 files changed, 503 insertions(+), 95 deletions(-) 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 0af24e0..03def5f 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 @@ -27,51 +27,14 @@ public class CustomButton extends CustomAbstractButton { final var g2d = (Graphics2D) g; final Theme theme = this.themeManager.getCurrentTheme(); + final var patternRenderer = this.themeManager.getPatternRenderer(theme.getPatternRendererName()); - float h, s, b; + if (patternRenderer != null) { + patternRenderer.drawButton(g2d, 0, 0, this.getWidth(), this.getHeight(), this.isEnabled(), this.state, this.backgroundColor, this.scaleFactor, theme); + } - final var borderStrength = (this.getWidth() < 48 || this.getHeight() < 48) ? 1 : 2; final var bgrStrength = (this.getWidth() < 48 || this.getHeight() < 48) ? 0 : 2; - if (this.backgroundColor == null) { - // Use theme colors - final var baseColor = (this.state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); - h = baseColor.getHue(); - s = baseColor.getSaturation(); - b = baseColor.getBrightness(); - - if ((this.state & STATE_PRESSED) != 0) { - b += theme.getPressedBrightnessAdjustment(); - } - else if ((this.state & STATE_HOVERED) != 0) { - b += theme.getHoverBrightnessAdjustment(); - } - } - else { - // Use custom background color - final var hsb = new float[3]; - Color.RGBtoHSB(this.backgroundColor.getRed(), this.backgroundColor.getGreen(), this.backgroundColor.getBlue(), hsb); - h = hsb[0]; - s = hsb[1]; - - if ((this.state & STATE_TOGGLED) == 0) { - b = 0.30F; - } - else { - b = 0.50F; - } - if ((this.state & STATE_PRESSED) != 0) { - b += theme.getPressedBrightnessAdjustment(); - } - else if ((this.state & STATE_HOVERED) != 0) { - b += theme.getHoverBrightnessAdjustment(); - } - } - - b = Math.max(0.0f, Math.min(1.0f, b)); - g2d.setColor(Color.getHSBColor(h, s, b)); - g2d.fillRect(2 + bgrStrength, 2 + bgrStrength, this.getWidth() - 5 - bgrStrength * 2, this.getHeight() - 5 - bgrStrength * 2); - if (this.iconResource != null && (this.icon == null || !this.iconResource.equals(this.loadedIconResource))) { this.loadIcon(); } @@ -79,7 +42,6 @@ public class CustomButton extends CustomAbstractButton { g2d.drawImage(this.icon, 4 + bgrStrength, 4 + bgrStrength, this.getWidth() - 4 - bgrStrength, this.getHeight() - 4 - bgrStrength, 0, 0, this.icon.getWidth(), this.icon.getHeight(), null); } else if (this.caption != null) { - // Text color based on state if ((this.state & STATE_HOVERED) != 0) { g2d.setColor(theme.getTextNormal().adjustBrightness(theme.getHoverBrightnessAdjustment()).toColor()); } @@ -101,18 +63,6 @@ public class CustomButton extends CustomAbstractButton { this.fontSize, this.caption); } - - // Draw borders using theme colors and pattern renderer - var borderColor = (this.state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : theme.getBorderOuter().toColor(); - final var patternRenderer = this.themeManager.getPatternRenderer(theme.getPatternRendererName()); - if (patternRenderer != null) { - patternRenderer.drawDecorativeBorder(g2d, 0, 0, this.getWidth() - 1, this.getHeight() - 1, borderStrength, borderColor); - - borderColor = this.isEnabled() ? - (this.state & STATE_HOVERED) != 0 ? theme.getSelectionSecondary().toColor() : theme.getBorderInner().toColor() : - theme.getBorderInnerDisabled().toColor(); - patternRenderer.drawDecorativeBorder(g2d, borderStrength, borderStrength, this.getWidth() - 1 - 2 * borderStrength, this.getHeight() - 1 - 2 * borderStrength, borderStrength, borderColor); - } } } 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 3cde1ab..709fbe7 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 @@ -28,59 +28,22 @@ public class CustomSwitch extends CustomAbstractButton { final var g2d = (Graphics2D) g; final Theme theme = this.themeManager.getCurrentTheme(); + final var patternRenderer = this.themeManager.getPatternRenderer(theme.getPatternRendererName()); final var dimY = this.getHeight() - 1; final var dimX = (int) (dimY * 1.5); - float h, s, b; - final var baseColor = (this.state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); - h = baseColor.getHue(); - s = baseColor.getSaturation(); - b = baseColor.getBrightness(); - - if ((this.state & STATE_PRESSED) != 0) { - b += theme.getPressedBrightnessAdjustment(); - } - else if ((this.state & STATE_HOVERED) != 0) { - b += theme.getHoverBrightnessAdjustment(); - } - - b = Math.max(0.0f, Math.min(1.0f, b)); - final var bodyColor = Color.getHSBColor(h, s, b); - Color border0Color; - Color border1Color; - - if (dimX < 45) { - border0Color = this.isEnabled() ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); - border1Color = bodyColor; - } - else { - border0Color = theme.getBorderOuter().toColor(); - border1Color = this.isEnabled() ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); - } - if ((this.state & STATE_TOGGLED) == 0) { - g2d.setColor(bodyColor); - g2d.fillRect(8, 8, (int) (dimX / 1.5) - 12, this.getHeight() - 15); - - final var patternRenderer = this.themeManager.getPatternRenderer(theme.getPatternRendererName()); if (patternRenderer != null) { - patternRenderer.drawDecorativeBorder(g2d, 6, 4, (int) (dimX / 1.5) - 6, this.getHeight() - 9, 2, border0Color); - patternRenderer.drawDecorativeBorder(g2d, 8, 6, (int) (dimX / 1.5) - 10, this.getHeight() - 13, 2, border1Color); + patternRenderer.drawButton(g2d, 6, 4, (int) (dimX / 1.5) - 6, this.getHeight() - 9, this.isEnabled(), this.state, null, this.scaleFactor, theme); } } else { - g2d.setColor(bodyColor); - g2d.fillRect(dimX - (int) (dimX / 1.5), 8, (int) (dimX / 1.5) - 12, this.getHeight() - 15); - - final var patternRenderer = this.themeManager.getPatternRenderer(theme.getPatternRendererName()); if (patternRenderer != null) { - patternRenderer.drawDecorativeBorder(g2d, dimX - (int) (dimX / 1.5) - 3, 4, (int) (dimX / 1.5) - 6, this.getHeight() - 9, 2, border0Color); - patternRenderer.drawDecorativeBorder(g2d, dimX - (int) (dimX / 1.5) - 1, 6, (int) (dimX / 1.5) - 10, this.getHeight() - 13, 2, border1Color); + patternRenderer.drawButton(g2d, dimX - (int) (dimX / 1.5) - 3, 4, (int) (dimX / 1.5) - 6, this.getHeight() - 9, this.isEnabled(), this.state, null, this.scaleFactor, theme); } } - // Text color based on state if ((this.state & STATE_HOVERED) != 0) { g2d.setColor(theme.getTextNormal().adjustBrightness(theme.getHoverBrightnessAdjustment()).toColor()); } @@ -104,7 +67,6 @@ public class CustomSwitch extends CustomAbstractButton { if (this.drawBorder) { final var borderColor1 = (this.state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : theme.getBorderOuter().toColor(); - final var patternRenderer = this.themeManager.getPatternRenderer(theme.getPatternRendererName()); if (patternRenderer != null) { patternRenderer.drawDecorativeBorder(g2d, 0, 0, this.getWidth() - 1, this.getHeight() - 1, 2, borderColor1); 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 index 79a961a..5df410e 100644 --- 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 @@ -136,4 +136,63 @@ public class BevelPatternRenderer implements PatternRenderer { } } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + int bevelStrength = (int) (2 * scaleFactor); + if (bevelStrength < 1) + bevelStrength = 1; + + final boolean pressed = (state & STATE_PRESSED) != 0; + final Color highlight = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : theme.getBorderOuter().toColor(); + final Color shadow = enabled ? + (state & STATE_HOVERED) != 0 ? theme.getSelectionSecondary().toColor() : theme.getBorderInner().toColor() : + theme.getBorderInnerDisabled().toColor(); + + drawBevel(g2d, x, y, width, height, bevelStrength, !pressed, highlight, shadow); + } } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/BlueprintPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BlueprintPatternRenderer.java index 0f6e96f..592c883 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/BlueprintPatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/BlueprintPatternRenderer.java @@ -151,6 +151,58 @@ public class BlueprintPatternRenderer implements PatternRenderer { return this.patternCache; } + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderOuter().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } + @Override public void drawBackgroundPattern(final Graphics2D g2d, final CoordI2 offset, final CoordI2 viewPort) { final var cache = this.getPatternCache(); @@ -165,4 +217,5 @@ public class BlueprintPatternRenderer implements PatternRenderer { } } } + } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamPatternRenderer.java index a8f8ca9..ee9143c 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamPatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/DreamPatternRenderer.java @@ -135,4 +135,59 @@ public class DreamPatternRenderer implements PatternRenderer { } } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + final var bgColor2 = new Color(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), 210); + + final var arc = Math.max(6, (int) (10 * scaleFactor)); + g2d.setColor(bgColor2); + g2d.fillRoundRect(x, y, width, height, arc, arc); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } } 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 f9c4161..938b98b 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 @@ -143,4 +143,56 @@ public class FantasyPatternRenderer implements PatternRenderer { } } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } } 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 index 47bc130..83a2c19 100644 --- 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 @@ -145,4 +145,56 @@ public class MetroPatternRenderer implements PatternRenderer { } } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBordersMain(g2d, x, y, width, height, borderStrength, width >= 48 && height >= 48, borderColor); + } } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernPatternRenderer.java index 1265143..60564c2 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernPatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/ModernPatternRenderer.java @@ -136,4 +136,56 @@ public class ModernPatternRenderer implements PatternRenderer { } } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/PatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/PatternRenderer.java index 4937bfd..6e0bc0a 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/PatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/PatternRenderer.java @@ -75,4 +75,20 @@ public interface PatternRenderer { * @param viewPort Viewport size */ void drawBackgroundPattern(final Graphics2D g2d, final CoordI2 offset, final CoordI2 viewPort); + + /** + * Draws a button background and borders with appropriate styling based on state. + * + * @param g2d The graphics context + * @param x X position + * @param y Y position + * @param width Width of the button + * @param height Height of the button + * @param enabled Whether the button is enabled + * @param state Button state flags (normal, hovered, pressed, toggled) + * @param backgroundColor Optional background color override (null to use theme defaults) + * @param scaleFactor UI scale factor + * @param theme Theme to use for colors + */ + void drawButton(Graphics2D g2d, int x, int y, int width, int height, boolean enabled, int state, Color backgroundColor, double scaleFactor, Theme theme); } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/SpacecraftPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/SpacecraftPatternRenderer.java index cf1c264..206300f 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/SpacecraftPatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/SpacecraftPatternRenderer.java @@ -173,4 +173,56 @@ public class SpacecraftPatternRenderer implements PatternRenderer { } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(2, (int) (3 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanPatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanPatternRenderer.java index f7eb12d..abacf28 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanPatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/UrbanPatternRenderer.java @@ -127,4 +127,56 @@ public class UrbanPatternRenderer implements PatternRenderer { } } } + + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y, width, height); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } } diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/theme/VintagePatternRenderer.java b/src/main/java/de/extio/game_engine/renderer/g2d/theme/VintagePatternRenderer.java index 3f5731e..763fcc2 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/theme/VintagePatternRenderer.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/theme/VintagePatternRenderer.java @@ -170,6 +170,59 @@ public class VintagePatternRenderer implements PatternRenderer { return this.patternCache; } + @Override + public void drawButton(final Graphics2D g2d, final int x, final int y, final int width, final int height, final boolean enabled, final int state, final Color backgroundColor, final double scaleFactor, final Theme theme) { + final int STATE_TOGGLED = 1; + final int STATE_PRESSED = 2; + final int STATE_HOVERED = 4; + + float h, s, b; + + if (backgroundColor == null) { + final var baseColor = (state & STATE_TOGGLED) == 0 ? theme.getBackgroundNormal() : theme.getBackgroundSelected(); + h = baseColor.getHue(); + s = baseColor.getSaturation(); + b = baseColor.getBrightness(); + + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + else { + final var hsb = new float[3]; + Color.RGBtoHSB(backgroundColor.getRed(), backgroundColor.getGreen(), backgroundColor.getBlue(), hsb); + h = hsb[0]; + s = hsb[1]; + + if ((state & STATE_TOGGLED) == 0) { + b = 0.30F; + } + else { + b = 0.50F; + } + if ((state & STATE_PRESSED) != 0) { + b += theme.getPressedBrightnessAdjustment(); + } + else if ((state & STATE_HOVERED) != 0) { + b += theme.getHoverBrightnessAdjustment(); + } + } + + b = Math.max(0.0f, Math.min(1.0f, b)); + final var bgColor = Color.getHSBColor(h, s, b); + g2d.setColor(bgColor); + g2d.fillRect(x, y + 1, width, height - 3); + g2d.fillRect(x + 1, y + height - 2, width - 2, 1); + + final var borderStrength = Math.max(1, (int) (2 * scaleFactor)); + final var borderColor = (state & STATE_HOVERED) != 0 ? theme.getSelectionPrimary().toColor() : + enabled ? theme.getBorderInner().toColor() : theme.getBorderInnerDisabled().toColor(); + this.drawDecorativeBorder(g2d, x, y, width, height, borderStrength, borderColor); + } + @Override public void drawBackgroundPattern(final Graphics2D g2d, final CoordI2 offset, final CoordI2 viewPort) { final var cache = this.getPatternCache();