// example_app.dart // Pyramid Players · Showcase / Test-Harness // // Zeigt alle Player-Varianten in einem scrollbaren Dark-Layout. // Drop-in-fähig: füge die drei Pyramid-Dateien (theme + audio + video) // in dein Projekt und referenziere sie wie unten. import 'package:flutter/material.dart'; import 'pyramid_theme.dart'; import 'pyramid_audio_player.dart'; import 'pyramid_video_player.dart'; void main() => runApp(const PyramidShowcaseApp()); class PyramidShowcaseApp extends StatelessWidget { const PyramidShowcaseApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Pyramid · Players', theme: ThemeData( scaffoldBackgroundColor: PyramidTheme.bg0, fontFamily: PyramidTheme.fontSans, useMaterial3: true, ), home: const _Showcase(), ); } } class _Showcase extends StatefulWidget { const _Showcase(); @override State<_Showcase> createState() => _ShowcaseState(); } class _ShowcaseState extends State<_Showcase> { bool _playing = true; Duration _audioPos = const Duration(minutes: 1, seconds: 11); final _audioDur = const Duration(minutes: 3, seconds: 24); Duration _videoPos = const Duration(minutes: 1, seconds: 28); final _videoDur = const Duration(minutes: 4, seconds: 12); void _toggle() => setState(() => _playing = !_playing); @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB(48, 48, 48, 120), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('PYRAMID · MEDIA PLAYERS', style: TextStyle(fontFamily: PyramidTheme.fontMono, fontSize: 10, letterSpacing: 1.4, color: PyramidTheme.fgDim)), const SizedBox(height: 6), Text('Audio + Video — Flutter', style: TextStyle(color: PyramidTheme.fg, fontSize: 28, fontWeight: FontWeight.w500)), const SizedBox(height: 40), _section('AUDIO'), _grid([ _frame('01 · Default', 'chunky bars', PyramidAudioPlayer( variant: AudioPlayerVariant.defaultBars, title: 'test track', artist: 'pyramid · demo', duration: _audioDur, position: _audioPos, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _audioPos = p), )), _frame('02 · Gracile', 'hairline wave', PyramidAudioPlayer( variant: AudioPlayerVariant.gracile, title: 'test track', artist: 'pyramid · demo', duration: _audioDur, position: _audioPos, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _audioPos = p), )), _frame('03 · Compact', 'in-chat', PyramidAudioPlayer( variant: AudioPlayerVariant.compact, title: 'test track', artist: 'pyramid · demo', duration: _audioDur, position: _audioPos, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _audioPos = p), )), _frame('04 · Mono', 'terminal', PyramidAudioPlayer( variant: AudioPlayerVariant.mono, title: 'test.wav', artist: 'pyramid · demo', duration: _audioDur, position: _audioPos, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _audioPos = p), )), ]), const SizedBox(height: 40), _section('VIDEO'), _grid([ _frame('01 · Default', 'hover-chrome', PyramidVideoPlayer( variant: VideoPlayerVariant.defaultHover, title: 'test clip', subtitle: 'pyramid · 1080p', duration: _videoDur, position: _videoPos, buffered: 0.65, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _videoPos = p), )), _frame('02 · Minimal', 'always-visible', PyramidVideoPlayer( variant: VideoPlayerVariant.minimal, title: 'test clip', subtitle: 'pyramid · 1080p', duration: _videoDur, position: _videoPos, buffered: 0.65, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _videoPos = p), )), _frame('03 · Framed', 'editorial', PyramidVideoPlayer( variant: VideoPlayerVariant.framed, title: 'test clip', subtitle: 'pyramid · 1080p', duration: _videoDur, position: _videoPos, buffered: 0.65, playing: _playing, onTogglePlay: _toggle, onSeek: (p) => setState(() => _videoPos = p), )), ]), ]), ), ), ); } Widget _section(String label) => Padding( padding: const EdgeInsets.only(bottom: 20), child: Container( padding: const EdgeInsets.only(bottom: 8), decoration: BoxDecoration(border: Border(bottom: BorderSide(color: PyramidTheme.border))), child: Text(label, style: TextStyle(fontFamily: PyramidTheme.fontMono, fontSize: 10, letterSpacing: 1.8, color: PyramidTheme.fgDim)), ), ); Widget _frame(String label, String sub, Widget child) => Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.only(bottom: 14), child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(fontFamily: PyramidTheme.fontMono, fontSize: 10, letterSpacing: 1.4, color: PyramidTheme.fgMuted)), Text(sub, style: TextStyle(fontFamily: PyramidTheme.fontMono, fontSize: 10, letterSpacing: 1.4, color: PyramidTheme.fgDim)), ]), ), child, ], ); Widget _grid(List items) => Wrap( spacing: 28, runSpacing: 28, children: items.map((i) => SizedBox(width: 420, child: i)).toList(), ); }