Moved all widgets and logic from gui app to Flutter package
- Implemented DebugToolsScreen for navigation to asset galleries. - Created GameScreen to manage gameplay and renderer integrations. - Added NoGameDataScreen to handle scenarios with missing game data. - Developed SpriteGallery for visual browsing of sprite assets. - Introduced VgaGallery for displaying VGA images from game data. - Added GalleryGameSelector widget for selecting game variants in galleries. - Created Wolf3dApp as the main application shell for managing game states. - Implemented WolfMenuShell for consistent menu layouts across screens. - Enhanced Wolf3d class to support debug mode and related functionalities. - Updated pubspec.yaml to include window_manager dependency. - Added tests for game screen lifecycle and debug mode functionalities. Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
|
||||
import 'package:wolf_3d_flutter/wolf_3d_flutter.dart';
|
||||
|
||||
/// Human-readable title for a game variant in gallery selectors.
|
||||
String formatGalleryGameTitle(GameVersion version) {
|
||||
switch (version) {
|
||||
case GameVersion.shareware:
|
||||
return 'SHAREWARE';
|
||||
case GameVersion.retail:
|
||||
return 'RETAIL';
|
||||
case GameVersion.spearOfDestiny:
|
||||
return 'SPEAR OF DESTINY';
|
||||
case GameVersion.spearOfDestinyDemo:
|
||||
return 'SOD DEMO';
|
||||
}
|
||||
}
|
||||
|
||||
/// Selects which discovered game data set gallery screens should display.
|
||||
class GalleryGameSelector extends StatelessWidget {
|
||||
final Wolf3d wolf3d;
|
||||
final WolfensteinData selectedGame;
|
||||
final ValueChanged<WolfensteinData> onSelected;
|
||||
|
||||
const GalleryGameSelector({
|
||||
super.key,
|
||||
required this.wolf3d,
|
||||
required this.selectedGame,
|
||||
required this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: Center(
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<WolfensteinData>(
|
||||
value: selectedGame,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
dropdownColor: Theme.of(context).colorScheme.surface,
|
||||
iconEnabledColor: Theme.of(context).colorScheme.onSurface,
|
||||
onChanged: (WolfensteinData? game) {
|
||||
if (game != null) {
|
||||
onSelected(game);
|
||||
}
|
||||
},
|
||||
items: wolf3d.availableGames.map((WolfensteinData game) {
|
||||
return DropdownMenuItem<WolfensteinData>(
|
||||
value: game,
|
||||
child: Text(formatGalleryGameTitle(game.version)),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wolf_3d_flutter/wolf_3d_flutter.dart';
|
||||
|
||||
/// Minimal app shell that binds a prepared [Wolf3d] instance to host screens.
|
||||
class Wolf3dApp extends StatelessWidget {
|
||||
/// Shared initialized facade that owns game data, input, and audio services.
|
||||
final Wolf3d wolf3d;
|
||||
|
||||
const Wolf3dApp({
|
||||
super.key,
|
||||
required this.wolf3d,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return wolf3d.availableGames.isEmpty
|
||||
? const NoGameDataScreen()
|
||||
: GameScreen(wolf3d: wolf3d);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/// Shared shell for Wolf3D-style menu screens.
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
|
||||
import 'package:wolf_3d_flutter/renderer/wolf_3d_asset_painter.dart';
|
||||
|
||||
/// Provides a common menu layout with panel framing and optional bottom art.
|
||||
class WolfMenuShell extends StatelessWidget {
|
||||
/// Full-screen background color behind the panel.
|
||||
final Color backgroundColor;
|
||||
|
||||
/// Solid panel fill used for the menu content area.
|
||||
final Color panelColor;
|
||||
|
||||
/// Optional heading shown above the panel (text or image).
|
||||
final Widget? header;
|
||||
|
||||
/// Primary menu content rendered inside the panel.
|
||||
final Widget panelChild;
|
||||
|
||||
/// Optional centered VGA image anchored near the bottom of the screen.
|
||||
final VgaImage? bottomSprite;
|
||||
|
||||
/// Width of the menu panel.
|
||||
final double panelWidth;
|
||||
|
||||
/// Padding applied around [panelChild] inside the panel.
|
||||
final EdgeInsets panelPadding;
|
||||
|
||||
/// Scale factor for [bottomSprite].
|
||||
final double bottomSpriteScale;
|
||||
|
||||
/// Distance from the bottom edge for [bottomSprite].
|
||||
final double bottomOffset;
|
||||
|
||||
/// Vertical spacing between [header] and the panel.
|
||||
final double headerSpacing;
|
||||
|
||||
const WolfMenuShell({
|
||||
super.key,
|
||||
required this.backgroundColor,
|
||||
required this.panelColor,
|
||||
required this.panelChild,
|
||||
this.header,
|
||||
this.bottomSprite,
|
||||
this.panelWidth = 520,
|
||||
this.panelPadding = const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 16,
|
||||
),
|
||||
this.bottomSpriteScale = 3,
|
||||
this.bottomOffset = 20,
|
||||
this.headerSpacing = 14,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: ColoredBox(color: backgroundColor),
|
||||
),
|
||||
Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (header case final Widget value) value,
|
||||
if (header != null) SizedBox(height: headerSpacing),
|
||||
Container(
|
||||
width: panelWidth,
|
||||
padding: panelPadding,
|
||||
color: panelColor,
|
||||
child: panelChild,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (bottomSprite != null)
|
||||
Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: bottomOffset,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: bottomSprite!.width * bottomSpriteScale,
|
||||
height: bottomSprite!.height * bottomSpriteScale,
|
||||
child: WolfAssetPainter.vga(bottomSprite),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user