From 62dca47d1d2ffe01fff8a8d2d73af06467285b3a Mon Sep 17 00:00:00 2001 From: Hans Kokx Date: Tue, 24 Mar 2026 14:58:47 +0100 Subject: [PATCH] feat: Refactor color handling in NoGameDataScreen and ColorPalette for improved clarity and maintainability Signed-off-by: Hans Kokx --- apps/wolf_3d_gui/lib/no_game_data_screen.dart | 44 +++++++++++-------- .../lib/src/data_types/color_palette.dart | 13 ++++++ packages/wolf_3d_dart/lib/wolf_3d_menu.dart | 38 ++++------------ 3 files changed, 48 insertions(+), 47 deletions(-) diff --git a/apps/wolf_3d_gui/lib/no_game_data_screen.dart b/apps/wolf_3d_gui/lib/no_game_data_screen.dart index d7df97f..781e259 100644 --- a/apps/wolf_3d_gui/lib/no_game_data_screen.dart +++ b/apps/wolf_3d_gui/lib/no_game_data_screen.dart @@ -53,26 +53,34 @@ class NoGameDataScreen extends StatelessWidget { /// Currently selected ready version. final GameVersion? selectedReadyVersion; - static Color _colorFromVgaIndex(int index) { - final int packed = ColorPalette.vga32Bit[index]; - final int r = packed & 0xFF; - final int g = (packed >> 8) & 0xFF; - final int b = (packed >> 16) & 0xFF; - return Color((0xFF << 24) | (r << 16) | (g << 8) | b); - } - - static final Color _backgroundColor = _colorFromVgaIndex(111); - static final Color _panelColor = _colorFromVgaIndex(103); - static final Color _borderColor = _colorFromVgaIndex(87); - static final Color _titleColor = _colorFromVgaIndex( - WolfMenuPalette.headerTextIndex, + static final Color _backgroundColor = Color( + ColorPalette.argbFromVgaIndex(WolfMenuPalette.backgroundIndex), ); - static final Color _bodyColor = _colorFromVgaIndex( - WolfMenuPalette.unselectedTextIndex, + static final Color _panelColor = Color( + ColorPalette.argbFromVgaIndex(WolfMenuPalette.panelIndex), + ); + static final Color _borderColor = Color( + ColorPalette.argbFromVgaIndex(WolfMenuPalette.borderIndex), + ); + static final Color _titleColor = Color( + ColorPalette.argbFromVgaIndex( + WolfMenuPalette.headerTextIndex, + ), + ); + static final Color _bodyColor = Color( + ColorPalette.argbFromVgaIndex( + WolfMenuPalette.unselectedTextIndex, + ), + ); + static final Color _emphasisColor = Color( + ColorPalette.argbFromVgaIndex(WolfMenuPalette.emphasisIndex), + ); + static final Color _warningColor = Color( + ColorPalette.argbFromVgaIndex(WolfMenuPalette.warningIndex), + ); + static final Color _mutedColor = Color( + ColorPalette.argbFromVgaIndex(WolfMenuPalette.mutedIndex), ); - static final Color _emphasisColor = _colorFromVgaIndex(10); - static final Color _warningColor = _colorFromVgaIndex(14); - static final Color _mutedColor = _colorFromVgaIndex(8); static String _stateLabel(GameDataVersionState state) { switch (state) { diff --git a/packages/wolf_3d_dart/lib/src/data_types/color_palette.dart b/packages/wolf_3d_dart/lib/src/data_types/color_palette.dart index 2dc5a4e..9b20169 100644 --- a/packages/wolf_3d_dart/lib/src/data_types/color_palette.dart +++ b/packages/wolf_3d_dart/lib/src/data_types/color_palette.dart @@ -262,6 +262,19 @@ abstract class ColorPalette { 0xFF890099, ]); + /// Converts a VGA palette index to a packed 32-bit ARGB color. + /// + /// Internally, [vga32Bit] stores channel bytes in ABGR order for renderer + /// pipelines that write raw bytes directly. This helper returns standard + /// ARGB (`0xAARRGGBB`) for APIs that expect Flutter/Dart UI color packing. + static int argbFromVgaIndex(int index) { + final int packed = vga32Bit[index]; + final int r = packed & 0xFF; + final int g = (packed >> 8) & 0xFF; + final int b = (packed >> 16) & 0xFF; + return (0xFF << 24) | (r << 16) | (g << 8) | b; + } + static int findClosestPaletteIndex(int argb) { final int targetR = (argb >> 16) & 0xFF; final int targetG = (argb >> 8) & 0xFF; diff --git a/packages/wolf_3d_dart/lib/wolf_3d_menu.dart b/packages/wolf_3d_dart/lib/wolf_3d_menu.dart index 1a782df..0cd23b7 100644 --- a/packages/wolf_3d_dart/lib/wolf_3d_menu.dart +++ b/packages/wolf_3d_dart/lib/wolf_3d_menu.dart @@ -49,6 +49,13 @@ abstract class WolfMenuPic { /// Keep menu color choices centralized so renderers don't duplicate /// hard-coded palette slots or RGB conversion logic. abstract class WolfMenuPalette { + static const int backgroundIndex = 111; + static const int panelIndex = 103; + static const int borderIndex = 87; + static const int emphasisIndex = 10; + static const int warningIndex = 14; + static const int mutedIndex = 8; + static const int selectedTextIndex = 19; static const int unselectedTextIndex = 23; static const int disabledTextIndex = 4; @@ -56,8 +63,8 @@ abstract class WolfMenuPalette { static int? _cachedHeaderTextIndex; - static int get headerTextIndex => - _cachedHeaderTextIndex ??= _nearestPaletteIndex(_headerTargetRgb); + static int get headerTextIndex => _cachedHeaderTextIndex ??= + ColorPalette.findClosestPaletteIndex(_headerTargetRgb); static int get selectedTextColor => ColorPalette.vga32Bit[selectedTextIndex]; @@ -67,33 +74,6 @@ abstract class WolfMenuPalette { static int get disabledTextColor => ColorPalette.vga32Bit[disabledTextIndex]; static int get headerTextColor => ColorPalette.vga32Bit[headerTextIndex]; - - static int _nearestPaletteIndex(int rgb) { - final int targetR = (rgb >> 16) & 0xFF; - final int targetG = (rgb >> 8) & 0xFF; - final int targetB = rgb & 0xFF; - - int bestIndex = 0; - int bestDistance = 1 << 30; - - for (int i = 0; i < 256; i++) { - final int color = ColorPalette.vga32Bit[i]; - final int r = color & 0xFF; - final int g = (color >> 8) & 0xFF; - final int b = (color >> 16) & 0xFF; - - final int dr = targetR - r; - final int dg = targetG - g; - final int db = targetB - b; - final int distance = (dr * dr) + (dg * dg) + (db * db); - if (distance < bestDistance) { - bestDistance = distance; - bestIndex = i; - } - } - - return bestIndex; - } } /// Structured accessors for classic Wolf3D menu art.