From 7a0d57b2b15c0e06b2f18cf188f5674aab38dc6c Mon Sep 17 00:00:00 2001 From: funman300 Date: Wed, 13 May 2026 22:41:38 -0700 Subject: [PATCH] feat(engine): add Classic card theme White/cream card faces with traditional red (hearts/diamonds) and black (clubs/spades) colours, plus a navy diamond-pattern card back. Shipped as a bundled AssetServer theme alongside the existing Default theme. Registry updated to include the Classic entry; registry tests updated to reflect the new BUNDLED_COUNT of 2. Co-Authored-By: Claude Sonnet 4.6 --- .../assets/themes/classic/back.svg | 19 ++++++ .../assets/themes/classic/clubs_10.svg | 25 ++++++++ .../assets/themes/classic/clubs_2.svg | 25 ++++++++ .../assets/themes/classic/clubs_3.svg | 25 ++++++++ .../assets/themes/classic/clubs_4.svg | 25 ++++++++ .../assets/themes/classic/clubs_5.svg | 25 ++++++++ .../assets/themes/classic/clubs_6.svg | 25 ++++++++ .../assets/themes/classic/clubs_7.svg | 25 ++++++++ .../assets/themes/classic/clubs_8.svg | 25 ++++++++ .../assets/themes/classic/clubs_9.svg | 25 ++++++++ .../assets/themes/classic/clubs_ace.svg | 25 ++++++++ .../assets/themes/classic/clubs_jack.svg | 25 ++++++++ .../assets/themes/classic/clubs_king.svg | 25 ++++++++ .../assets/themes/classic/clubs_queen.svg | 25 ++++++++ .../assets/themes/classic/diamonds_10.svg | 25 ++++++++ .../assets/themes/classic/diamonds_2.svg | 25 ++++++++ .../assets/themes/classic/diamonds_3.svg | 25 ++++++++ .../assets/themes/classic/diamonds_4.svg | 25 ++++++++ .../assets/themes/classic/diamonds_5.svg | 25 ++++++++ .../assets/themes/classic/diamonds_6.svg | 25 ++++++++ .../assets/themes/classic/diamonds_7.svg | 25 ++++++++ .../assets/themes/classic/diamonds_8.svg | 25 ++++++++ .../assets/themes/classic/diamonds_9.svg | 25 ++++++++ .../assets/themes/classic/diamonds_ace.svg | 25 ++++++++ .../assets/themes/classic/diamonds_jack.svg | 25 ++++++++ .../assets/themes/classic/diamonds_king.svg | 25 ++++++++ .../assets/themes/classic/diamonds_queen.svg | 25 ++++++++ .../assets/themes/classic/hearts_10.svg | 25 ++++++++ .../assets/themes/classic/hearts_2.svg | 25 ++++++++ .../assets/themes/classic/hearts_3.svg | 25 ++++++++ .../assets/themes/classic/hearts_4.svg | 25 ++++++++ .../assets/themes/classic/hearts_5.svg | 25 ++++++++ .../assets/themes/classic/hearts_6.svg | 25 ++++++++ .../assets/themes/classic/hearts_7.svg | 25 ++++++++ .../assets/themes/classic/hearts_8.svg | 25 ++++++++ .../assets/themes/classic/hearts_9.svg | 25 ++++++++ .../assets/themes/classic/hearts_ace.svg | 25 ++++++++ .../assets/themes/classic/hearts_jack.svg | 25 ++++++++ .../assets/themes/classic/hearts_king.svg | 25 ++++++++ .../assets/themes/classic/hearts_queen.svg | 25 ++++++++ .../assets/themes/classic/spades_10.svg | 25 ++++++++ .../assets/themes/classic/spades_2.svg | 25 ++++++++ .../assets/themes/classic/spades_3.svg | 25 ++++++++ .../assets/themes/classic/spades_4.svg | 25 ++++++++ .../assets/themes/classic/spades_5.svg | 25 ++++++++ .../assets/themes/classic/spades_6.svg | 25 ++++++++ .../assets/themes/classic/spades_7.svg | 25 ++++++++ .../assets/themes/classic/spades_8.svg | 25 ++++++++ .../assets/themes/classic/spades_9.svg | 25 ++++++++ .../assets/themes/classic/spades_ace.svg | 25 ++++++++ .../assets/themes/classic/spades_jack.svg | 25 ++++++++ .../assets/themes/classic/spades_king.svg | 25 ++++++++ .../assets/themes/classic/spades_queen.svg | 25 ++++++++ .../assets/themes/classic/theme.ron | 64 +++++++++++++++++++ solitaire_engine/src/theme/registry.rs | 39 ++++++++--- 55 files changed, 1414 insertions(+), 8 deletions(-) create mode 100644 solitaire_engine/assets/themes/classic/back.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_10.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_2.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_3.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_4.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_5.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_6.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_7.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_8.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_9.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_ace.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_jack.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_king.svg create mode 100644 solitaire_engine/assets/themes/classic/clubs_queen.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_10.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_2.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_3.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_4.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_5.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_6.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_7.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_8.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_9.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_ace.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_jack.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_king.svg create mode 100644 solitaire_engine/assets/themes/classic/diamonds_queen.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_10.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_2.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_3.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_4.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_5.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_6.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_7.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_8.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_9.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_ace.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_jack.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_king.svg create mode 100644 solitaire_engine/assets/themes/classic/hearts_queen.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_10.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_2.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_3.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_4.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_5.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_6.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_7.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_8.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_9.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_ace.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_jack.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_king.svg create mode 100644 solitaire_engine/assets/themes/classic/spades_queen.svg create mode 100644 solitaire_engine/assets/themes/classic/theme.ron diff --git a/solitaire_engine/assets/themes/classic/back.svg b/solitaire_engine/assets/themes/classic/back.svg new file mode 100644 index 0000000..04e1aec --- /dev/null +++ b/solitaire_engine/assets/themes/classic/back.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_10.svg b/solitaire_engine/assets/themes/classic/clubs_10.svg new file mode 100644 index 0000000..3acbad2 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_10.svg @@ -0,0 +1,25 @@ + + + + + 10 + + + + + + + + + + + + 10 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_2.svg b/solitaire_engine/assets/themes/classic/clubs_2.svg new file mode 100644 index 0000000..044df12 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_2.svg @@ -0,0 +1,25 @@ + + + + + 2 + + + + + + + + + + + + 2 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_3.svg b/solitaire_engine/assets/themes/classic/clubs_3.svg new file mode 100644 index 0000000..bf270c0 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_3.svg @@ -0,0 +1,25 @@ + + + + + 3 + + + + + + + + + + + + 3 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_4.svg b/solitaire_engine/assets/themes/classic/clubs_4.svg new file mode 100644 index 0000000..81230db --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_4.svg @@ -0,0 +1,25 @@ + + + + + 4 + + + + + + + + + + + + 4 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_5.svg b/solitaire_engine/assets/themes/classic/clubs_5.svg new file mode 100644 index 0000000..33ac3d9 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_5.svg @@ -0,0 +1,25 @@ + + + + + 5 + + + + + + + + + + + + 5 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_6.svg b/solitaire_engine/assets/themes/classic/clubs_6.svg new file mode 100644 index 0000000..f6043e3 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_6.svg @@ -0,0 +1,25 @@ + + + + + 6 + + + + + + + + + + + + 6 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_7.svg b/solitaire_engine/assets/themes/classic/clubs_7.svg new file mode 100644 index 0000000..7f1d837 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_7.svg @@ -0,0 +1,25 @@ + + + + + 7 + + + + + + + + + + + + 7 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_8.svg b/solitaire_engine/assets/themes/classic/clubs_8.svg new file mode 100644 index 0000000..01e8c04 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_8.svg @@ -0,0 +1,25 @@ + + + + + 8 + + + + + + + + + + + + 8 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_9.svg b/solitaire_engine/assets/themes/classic/clubs_9.svg new file mode 100644 index 0000000..fe9fcd6 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_9.svg @@ -0,0 +1,25 @@ + + + + + 9 + + + + + + + + + + + + 9 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_ace.svg b/solitaire_engine/assets/themes/classic/clubs_ace.svg new file mode 100644 index 0000000..ddadb51 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_ace.svg @@ -0,0 +1,25 @@ + + + + + A + + + + + + + + + + + + A + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_jack.svg b/solitaire_engine/assets/themes/classic/clubs_jack.svg new file mode 100644 index 0000000..3ed3344 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_jack.svg @@ -0,0 +1,25 @@ + + + + + J + + + + + + + + + + + + J + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_king.svg b/solitaire_engine/assets/themes/classic/clubs_king.svg new file mode 100644 index 0000000..d17460d --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_king.svg @@ -0,0 +1,25 @@ + + + + + K + + + + + + + + + + + + K + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/clubs_queen.svg b/solitaire_engine/assets/themes/classic/clubs_queen.svg new file mode 100644 index 0000000..5f8d53d --- /dev/null +++ b/solitaire_engine/assets/themes/classic/clubs_queen.svg @@ -0,0 +1,25 @@ + + + + + Q + + + + + + + + + + + + Q + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_10.svg b/solitaire_engine/assets/themes/classic/diamonds_10.svg new file mode 100644 index 0000000..0505bdf --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_10.svg @@ -0,0 +1,25 @@ + + + + + 10 + + + + + + + + + + + + 10 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_2.svg b/solitaire_engine/assets/themes/classic/diamonds_2.svg new file mode 100644 index 0000000..d77acc1 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_2.svg @@ -0,0 +1,25 @@ + + + + + 2 + + + + + + + + + + + + 2 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_3.svg b/solitaire_engine/assets/themes/classic/diamonds_3.svg new file mode 100644 index 0000000..b8e1459 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_3.svg @@ -0,0 +1,25 @@ + + + + + 3 + + + + + + + + + + + + 3 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_4.svg b/solitaire_engine/assets/themes/classic/diamonds_4.svg new file mode 100644 index 0000000..4a8f63d --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_4.svg @@ -0,0 +1,25 @@ + + + + + 4 + + + + + + + + + + + + 4 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_5.svg b/solitaire_engine/assets/themes/classic/diamonds_5.svg new file mode 100644 index 0000000..4c139b8 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_5.svg @@ -0,0 +1,25 @@ + + + + + 5 + + + + + + + + + + + + 5 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_6.svg b/solitaire_engine/assets/themes/classic/diamonds_6.svg new file mode 100644 index 0000000..6d2975e --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_6.svg @@ -0,0 +1,25 @@ + + + + + 6 + + + + + + + + + + + + 6 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_7.svg b/solitaire_engine/assets/themes/classic/diamonds_7.svg new file mode 100644 index 0000000..0970d1a --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_7.svg @@ -0,0 +1,25 @@ + + + + + 7 + + + + + + + + + + + + 7 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_8.svg b/solitaire_engine/assets/themes/classic/diamonds_8.svg new file mode 100644 index 0000000..884d3d6 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_8.svg @@ -0,0 +1,25 @@ + + + + + 8 + + + + + + + + + + + + 8 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_9.svg b/solitaire_engine/assets/themes/classic/diamonds_9.svg new file mode 100644 index 0000000..d883ccf --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_9.svg @@ -0,0 +1,25 @@ + + + + + 9 + + + + + + + + + + + + 9 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_ace.svg b/solitaire_engine/assets/themes/classic/diamonds_ace.svg new file mode 100644 index 0000000..d5ceb9d --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_ace.svg @@ -0,0 +1,25 @@ + + + + + A + + + + + + + + + + + + A + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_jack.svg b/solitaire_engine/assets/themes/classic/diamonds_jack.svg new file mode 100644 index 0000000..d024d76 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_jack.svg @@ -0,0 +1,25 @@ + + + + + J + + + + + + + + + + + + J + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_king.svg b/solitaire_engine/assets/themes/classic/diamonds_king.svg new file mode 100644 index 0000000..100767a --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_king.svg @@ -0,0 +1,25 @@ + + + + + K + + + + + + + + + + + + K + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/diamonds_queen.svg b/solitaire_engine/assets/themes/classic/diamonds_queen.svg new file mode 100644 index 0000000..2b8a26e --- /dev/null +++ b/solitaire_engine/assets/themes/classic/diamonds_queen.svg @@ -0,0 +1,25 @@ + + + + + Q + + + + + + + + + + + + Q + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_10.svg b/solitaire_engine/assets/themes/classic/hearts_10.svg new file mode 100644 index 0000000..7537453 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_10.svg @@ -0,0 +1,25 @@ + + + + + 10 + + + + + + + + + + + + 10 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_2.svg b/solitaire_engine/assets/themes/classic/hearts_2.svg new file mode 100644 index 0000000..f8189c9 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_2.svg @@ -0,0 +1,25 @@ + + + + + 2 + + + + + + + + + + + + 2 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_3.svg b/solitaire_engine/assets/themes/classic/hearts_3.svg new file mode 100644 index 0000000..af6114c --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_3.svg @@ -0,0 +1,25 @@ + + + + + 3 + + + + + + + + + + + + 3 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_4.svg b/solitaire_engine/assets/themes/classic/hearts_4.svg new file mode 100644 index 0000000..d6f36d0 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_4.svg @@ -0,0 +1,25 @@ + + + + + 4 + + + + + + + + + + + + 4 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_5.svg b/solitaire_engine/assets/themes/classic/hearts_5.svg new file mode 100644 index 0000000..82e89c6 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_5.svg @@ -0,0 +1,25 @@ + + + + + 5 + + + + + + + + + + + + 5 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_6.svg b/solitaire_engine/assets/themes/classic/hearts_6.svg new file mode 100644 index 0000000..23247df --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_6.svg @@ -0,0 +1,25 @@ + + + + + 6 + + + + + + + + + + + + 6 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_7.svg b/solitaire_engine/assets/themes/classic/hearts_7.svg new file mode 100644 index 0000000..09582a6 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_7.svg @@ -0,0 +1,25 @@ + + + + + 7 + + + + + + + + + + + + 7 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_8.svg b/solitaire_engine/assets/themes/classic/hearts_8.svg new file mode 100644 index 0000000..0d670d3 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_8.svg @@ -0,0 +1,25 @@ + + + + + 8 + + + + + + + + + + + + 8 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_9.svg b/solitaire_engine/assets/themes/classic/hearts_9.svg new file mode 100644 index 0000000..d368c9e --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_9.svg @@ -0,0 +1,25 @@ + + + + + 9 + + + + + + + + + + + + 9 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_ace.svg b/solitaire_engine/assets/themes/classic/hearts_ace.svg new file mode 100644 index 0000000..d247a85 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_ace.svg @@ -0,0 +1,25 @@ + + + + + A + + + + + + + + + + + + A + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_jack.svg b/solitaire_engine/assets/themes/classic/hearts_jack.svg new file mode 100644 index 0000000..cbe9165 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_jack.svg @@ -0,0 +1,25 @@ + + + + + J + + + + + + + + + + + + J + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_king.svg b/solitaire_engine/assets/themes/classic/hearts_king.svg new file mode 100644 index 0000000..a2d38a4 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_king.svg @@ -0,0 +1,25 @@ + + + + + K + + + + + + + + + + + + K + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/hearts_queen.svg b/solitaire_engine/assets/themes/classic/hearts_queen.svg new file mode 100644 index 0000000..5a09f2c --- /dev/null +++ b/solitaire_engine/assets/themes/classic/hearts_queen.svg @@ -0,0 +1,25 @@ + + + + + Q + + + + + + + + + + + + Q + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_10.svg b/solitaire_engine/assets/themes/classic/spades_10.svg new file mode 100644 index 0000000..d784b0f --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_10.svg @@ -0,0 +1,25 @@ + + + + + 10 + + + + + + + + + + + + 10 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_2.svg b/solitaire_engine/assets/themes/classic/spades_2.svg new file mode 100644 index 0000000..2ca80df --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_2.svg @@ -0,0 +1,25 @@ + + + + + 2 + + + + + + + + + + + + 2 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_3.svg b/solitaire_engine/assets/themes/classic/spades_3.svg new file mode 100644 index 0000000..9b80d49 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_3.svg @@ -0,0 +1,25 @@ + + + + + 3 + + + + + + + + + + + + 3 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_4.svg b/solitaire_engine/assets/themes/classic/spades_4.svg new file mode 100644 index 0000000..7c17a5e --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_4.svg @@ -0,0 +1,25 @@ + + + + + 4 + + + + + + + + + + + + 4 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_5.svg b/solitaire_engine/assets/themes/classic/spades_5.svg new file mode 100644 index 0000000..351a8a6 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_5.svg @@ -0,0 +1,25 @@ + + + + + 5 + + + + + + + + + + + + 5 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_6.svg b/solitaire_engine/assets/themes/classic/spades_6.svg new file mode 100644 index 0000000..93edae6 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_6.svg @@ -0,0 +1,25 @@ + + + + + 6 + + + + + + + + + + + + 6 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_7.svg b/solitaire_engine/assets/themes/classic/spades_7.svg new file mode 100644 index 0000000..432a91e --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_7.svg @@ -0,0 +1,25 @@ + + + + + 7 + + + + + + + + + + + + 7 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_8.svg b/solitaire_engine/assets/themes/classic/spades_8.svg new file mode 100644 index 0000000..47bc5ca --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_8.svg @@ -0,0 +1,25 @@ + + + + + 8 + + + + + + + + + + + + 8 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_9.svg b/solitaire_engine/assets/themes/classic/spades_9.svg new file mode 100644 index 0000000..365a5ad --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_9.svg @@ -0,0 +1,25 @@ + + + + + 9 + + + + + + + + + + + + 9 + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_ace.svg b/solitaire_engine/assets/themes/classic/spades_ace.svg new file mode 100644 index 0000000..c5940aa --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_ace.svg @@ -0,0 +1,25 @@ + + + + + A + + + + + + + + + + + + A + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_jack.svg b/solitaire_engine/assets/themes/classic/spades_jack.svg new file mode 100644 index 0000000..8b4fdfa --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_jack.svg @@ -0,0 +1,25 @@ + + + + + J + + + + + + + + + + + + J + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_king.svg b/solitaire_engine/assets/themes/classic/spades_king.svg new file mode 100644 index 0000000..9339b11 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_king.svg @@ -0,0 +1,25 @@ + + + + + K + + + + + + + + + + + + K + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/spades_queen.svg b/solitaire_engine/assets/themes/classic/spades_queen.svg new file mode 100644 index 0000000..b64359c --- /dev/null +++ b/solitaire_engine/assets/themes/classic/spades_queen.svg @@ -0,0 +1,25 @@ + + + + + Q + + + + + + + + + + + + Q + + + + + \ No newline at end of file diff --git a/solitaire_engine/assets/themes/classic/theme.ron b/solitaire_engine/assets/themes/classic/theme.ron new file mode 100644 index 0000000..8ee6523 --- /dev/null +++ b/solitaire_engine/assets/themes/classic/theme.ron @@ -0,0 +1,64 @@ +( + meta: ( + id: "classic", + name: "Classic", + author: "Ferrous Solitaire", + version: "1.0.0", + card_aspect: (2, 3), + ), + back: "back.svg", + faces: { + "clubs_ace": "clubs_ace.svg", + "clubs_2": "clubs_2.svg", + "clubs_3": "clubs_3.svg", + "clubs_4": "clubs_4.svg", + "clubs_5": "clubs_5.svg", + "clubs_6": "clubs_6.svg", + "clubs_7": "clubs_7.svg", + "clubs_8": "clubs_8.svg", + "clubs_9": "clubs_9.svg", + "clubs_10": "clubs_10.svg", + "clubs_jack": "clubs_jack.svg", + "clubs_queen": "clubs_queen.svg", + "clubs_king": "clubs_king.svg", + "diamonds_ace": "diamonds_ace.svg", + "diamonds_2": "diamonds_2.svg", + "diamonds_3": "diamonds_3.svg", + "diamonds_4": "diamonds_4.svg", + "diamonds_5": "diamonds_5.svg", + "diamonds_6": "diamonds_6.svg", + "diamonds_7": "diamonds_7.svg", + "diamonds_8": "diamonds_8.svg", + "diamonds_9": "diamonds_9.svg", + "diamonds_10": "diamonds_10.svg", + "diamonds_jack": "diamonds_jack.svg", + "diamonds_queen": "diamonds_queen.svg", + "diamonds_king": "diamonds_king.svg", + "hearts_ace": "hearts_ace.svg", + "hearts_2": "hearts_2.svg", + "hearts_3": "hearts_3.svg", + "hearts_4": "hearts_4.svg", + "hearts_5": "hearts_5.svg", + "hearts_6": "hearts_6.svg", + "hearts_7": "hearts_7.svg", + "hearts_8": "hearts_8.svg", + "hearts_9": "hearts_9.svg", + "hearts_10": "hearts_10.svg", + "hearts_jack": "hearts_jack.svg", + "hearts_queen": "hearts_queen.svg", + "hearts_king": "hearts_king.svg", + "spades_ace": "spades_ace.svg", + "spades_2": "spades_2.svg", + "spades_3": "spades_3.svg", + "spades_4": "spades_4.svg", + "spades_5": "spades_5.svg", + "spades_6": "spades_6.svg", + "spades_7": "spades_7.svg", + "spades_8": "spades_8.svg", + "spades_9": "spades_9.svg", + "spades_10": "spades_10.svg", + "spades_jack": "spades_jack.svg", + "spades_queen": "spades_queen.svg", + "spades_king": "spades_king.svg", + }, +) diff --git a/solitaire_engine/src/theme/registry.rs b/solitaire_engine/src/theme/registry.rs index fb8814e..62f1da2 100644 --- a/solitaire_engine/src/theme/registry.rs +++ b/solitaire_engine/src/theme/registry.rs @@ -101,6 +101,7 @@ fn build_registry_on_startup(mut registry: bevy::ecs::system::ResMut ThemeRegistry { let mut entries = Vec::new(); entries.push(default_entry()); + entries.push(classic_entry()); entries.extend(discover_user_themes(user_dir)); ThemeRegistry { entries } } @@ -122,6 +123,24 @@ fn default_entry() -> ThemeEntry { } } +/// Classic bundled theme — white card faces with traditional red/black +/// colour scheme, loaded from `assets/themes/classic/` via the default +/// AssetServer source. +fn classic_entry() -> ThemeEntry { + ThemeEntry { + id: "classic".to_string(), + display_name: "Classic".to_string(), + manifest_url: "themes/classic/theme.ron".to_string(), + meta: ThemeMeta { + id: "classic".to_string(), + name: "Classic".to_string(), + author: "Ferrous Solitaire".to_string(), + version: "1.0.0".to_string(), + card_aspect: (2, 3), + }, + } +} + /// Walks `user_dir`, treating every immediate subdirectory as a /// candidate theme. A subdirectory contributes one entry if and only /// if it contains a `theme.ron` whose `meta` block parses cleanly and @@ -238,20 +257,24 @@ mod tests { fs::write(dir.join("theme.ron"), manifest).unwrap(); } + // Number of always-present bundled themes (default + classic). + const BUNDLED_COUNT: usize = 2; + #[test] - fn empty_user_dir_yields_only_the_default_entry() { + fn empty_user_dir_yields_only_bundled_entries() { let tmp = tempfile::tempdir().unwrap(); let registry = build_registry(tmp.path()); - assert_eq!(registry.len(), 1); + assert_eq!(registry.len(), BUNDLED_COUNT); assert_eq!(registry.entries[0].id, "default"); + assert_eq!(registry.entries[1].id, "classic"); } #[test] - fn nonexistent_user_dir_still_yields_default() { + fn nonexistent_user_dir_still_yields_bundled_entries() { let registry = build_registry(Path::new( "/definitely/not/a/real/path/should/not/panic", )); - assert_eq!(registry.len(), 1); + assert_eq!(registry.len(), BUNDLED_COUNT); assert_eq!(registry.entries[0].id, "default"); } @@ -263,7 +286,7 @@ mod tests { write_manifest(&theme_dir, "midnight", "Midnight"); let registry = build_registry(tmp.path()); - assert_eq!(registry.len(), 2); + assert_eq!(registry.len(), BUNDLED_COUNT + 1); let entry = registry.find("midnight").expect("midnight registered"); assert_eq!(entry.display_name, "Midnight"); assert_eq!(entry.manifest_url, "themes://midnight/theme.ron"); @@ -309,7 +332,7 @@ mod tests { write_manifest(&theme_dir, "../etc/passwd", "Evil"); let registry = build_registry(tmp.path()); - assert_eq!(registry.len(), 1, "escape attempt must not register"); + assert_eq!(registry.len(), BUNDLED_COUNT, "escape attempt must not register"); assert_eq!(registry.entries[0].id, "default"); } @@ -321,7 +344,7 @@ mod tests { fs::write(lonely.join("readme.md"), "wrong filename").unwrap(); let registry = build_registry(tmp.path()); - assert_eq!(registry.len(), 1); + assert_eq!(registry.len(), BUNDLED_COUNT); } #[test] @@ -349,7 +372,7 @@ mod tests { refresh_registry(&mut registry, tmp.path()); - assert_eq!(registry.len(), 1); + assert_eq!(registry.len(), BUNDLED_COUNT); assert_eq!(registry.entries[0].id, "default"); assert!(registry.find("stale").is_none()); }