import 'package:flutter/material.dart'; import 'package:window_manager/window_manager.dart'; import '../../../shared/theme/app_theme.dart'; import '../../../shared/widgets/top_drag_area.dart'; class ControlsChrome extends StatelessWidget { final bool visible; final List topBar; final double topBarLeftInset; final double topBarTopInset; final Widget bottomBar; final Widget? centerBar; final VoidCallback? onControlsAreaTap; final ValueChanged? onControlsHoverChanged; final Widget? leftBar; final Widget? rightBar; final bool isWindowed; final bool isPip; const ControlsChrome({ super.key, required this.visible, required this.topBar, this.topBarLeftInset = 8, this.topBarTopInset = 8, required this.bottomBar, this.centerBar, this.leftBar, this.rightBar, required this.onControlsAreaTap, this.onControlsHoverChanged, this.isWindowed = false, this.isPip = false, }); Widget _withControlsAreaTap(Widget child) { final onTap = onControlsAreaTap; return GestureDetector( behavior: HitTestBehavior.opaque, onTap: onTap ?? () {}, child: child, ); } Widget _withTopDragHandle(Widget child) { if (isPip) { return DragToMoveArea(child: child); } return TopDragArea(enabled: isWindowed, child: child); } @override Widget build(BuildContext context) { final tokens = context.appTokens; return IgnorePointer( ignoring: !visible, child: AnimatedOpacity( opacity: visible ? 1 : 0, duration: const Duration(milliseconds: 160), child: Stack( fit: StackFit.expand, children: [ Positioned( left: 0, top: 0, right: 0, child: MouseRegion( onEnter: (_) => onControlsHoverChanged?.call(true), onExit: (_) => onControlsHoverChanged?.call(false), child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () {}, child: DecoratedBox( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Colors.black87, Colors.transparent], ), ), child: _withTopDragHandle( Padding( padding: EdgeInsets.fromLTRB( topBarLeftInset, topBarTopInset, tokens.chromeInset, isPip ? 12 : 28, ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: topBar, ), ), ), ), ), ), ), Positioned( left: 0, right: 0, bottom: 0, child: MouseRegion( onEnter: (_) => onControlsHoverChanged?.call(true), onExit: (_) => onControlsHoverChanged?.call(false), child: _withControlsAreaTap( Container( padding: EdgeInsets.fromLTRB( 0, isPip ? 8 : 20, 0, isPip ? 6 : 8, ), decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.bottomCenter, end: Alignment.topCenter, colors: [Colors.black87, Colors.transparent], ), ), child: bottomBar, ), ), ), ), if (leftBar != null) Positioned( left: 28, top: 0, bottom: 0, child: Center(child: leftBar!), ), if (rightBar != null) Positioned( right: 16, top: 0, bottom: 0, child: Center(child: rightBar!), ), if (centerBar != null) Positioned.fill( child: Center( child: MouseRegion( onEnter: (_) => onControlsHoverChanged?.call(true), onExit: (_) => onControlsHoverChanged?.call(false), child: centerBar!, ), ), ), ], ), ), ); } }