import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; /// Compass button widget for resetting map rotation to north /// Only visible when map is rotated (rotation != 0) class CompassMapPluginWidget extends StatefulWidget { const CompassMapPluginWidget({super.key}); @override _CompassMapPluginWidgetState createState() => _CompassMapPluginWidgetState(); } class _CompassMapPluginWidgetState extends State { late MapController _mapController; bool _isRotated = false; late Timer _rotationCheckTimer; @override void didChangeDependencies() { super.didChangeDependencies(); try { _mapController = MapController.of(context); _initRotationMonitoring(); } catch (_) { // Ignore - MapController may not be available yet } } void _initRotationMonitoring() { // Check rotation periodically (every 100ms) to detect changes _rotationCheckTimer = Timer.periodic(const Duration(milliseconds: 100), (_) { _checkRotation(); }); // Initial state check _checkRotation(); } void _checkRotation() { try { if (!mounted) { return; } final double rotation = _mapController.camera.rotation; final bool isRotated = rotation.abs() > 0.0; if (isRotated != _isRotated) { setState(() { _isRotated = isRotated; }); } } catch (e) { // Silently ignore errors (controller may not be ready) } } void _resetRotation() { try { final MapController controller = MapController.of(context); controller.rotate(0); } catch (_) { // Ignore - MapController may not be available } } @override Widget build(BuildContext context) { return LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) => Stack( fit: StackFit.expand, children: [ if (_isRotated) Positioned( top: 10.0, right: 10.0, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( children: [ _compassButton(context), ], ) ], ), ) ], )); } FloatingActionButton _compassButton(BuildContext context) { return FloatingActionButton( backgroundColor: Colors.black26, mini: true, heroTag: 'compass_button', tooltip: 'Go to North', onPressed: _resetRotation, child: const Icon(Icons.explore), ); } @override void dispose() { _rotationCheckTimer.cancel(); super.dispose(); } }