Files
wolf_dart/apps/wolf_3d_gui/lib/screens/vga_gallery.dart
Hans Kokx 03dd871a46 feat: Implement game selection in sprite and VGA galleries with GalleryGameSelector
refactor: Update VgaGallery and SpriteGallery to use selected game data
chore: Remove unused plugins from generated plugin registrant and CMake files
chore: Clean up pubspec.yaml by removing super_clipboard dependency

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
2026-03-20 15:53:24 +01:00

130 lines
3.8 KiB
Dart

/// Visual browser for decoded VGA pictures and UI art.
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';
import 'package:wolf_3d_gui/screens/gallery_game_selector.dart';
import 'package:wolf_3d_renderer/wolf_3d_asset_painter.dart';
/// Shows each VGA image extracted from the currently selected game data set.
class VgaGallery extends StatefulWidget {
/// Shared app facade used to access available game data sets.
final Wolf3d wolf3d;
/// Creates the gallery for the currently selected or browsed game.
const VgaGallery({super.key, required this.wolf3d});
@override
State<VgaGallery> createState() => _VgaGalleryState();
}
class _VgaGalleryState extends State<VgaGallery> {
late WolfensteinData _selectedGame;
List<VgaImage> get _images => _selectedGame.vgaImages;
@override
void initState() {
super.initState();
_selectedGame =
widget.wolf3d.maybeActiveGame ?? widget.wolf3d.availableGames.first;
}
void _selectGame(WolfensteinData game) {
if (identical(_selectedGame, game)) {
return;
}
widget.wolf3d.setActiveGame(game);
setState(() {
_selectedGame = game;
});
}
void _showImagePreviewDialog(BuildContext context, int index) {
final VgaImage image = _images[index];
showDialog<void>(
context: context,
builder: (dialogContext) {
return AlertDialog(
title: Text(
'Index: $index ${image.width} x ${image.height}',
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
actions: [
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(),
child: const Text('Close'),
),
],
content: Center(
child: AspectRatio(
aspectRatio: image.width / image.height,
child: WolfAssetPainter.vga(image),
),
),
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('VGA Image Gallery'),
actions: [
if (widget.wolf3d.availableGames.length > 1)
GalleryGameSelector(
wolf3d: widget.wolf3d,
selectedGame: _selectedGame,
onSelected: _selectGame,
),
],
),
backgroundColor: Colors.black,
body: GridView.builder(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: _images.length,
itemBuilder: (context, index) {
return Card(
color: Colors.blueGrey,
child: InkWell(
onTap: () => _showImagePreviewDialog(context, index),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
Text(
'Index: $index\n${_images[index].width} x ${_images[index].height}',
style: const TextStyle(color: Colors.white, fontSize: 12),
textAlign: TextAlign.center,
),
Expanded(
child: Center(
child: AspectRatio(
aspectRatio:
_images[index].width / _images[index].height,
child: WolfAssetPainter.vga(_images[index]),
),
),
),
],
),
),
);
},
),
);
}
}