From aaf79c90c91a987527d811a6dfe22142c3d07724 Mon Sep 17 00:00:00 2001 From: just_stuff_tm <133525672+just-stuff-tm@users.noreply.github.com> Date: Mon, 23 Feb 2026 00:01:13 -0500 Subject: [PATCH] feat: show los elevation icon --- lib/icons/los_icon.dart | 80 +++++++++++++++++++++++ lib/screens/line_of_sight_map_screen.dart | 3 +- lib/screens/map_screen.dart | 3 +- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 lib/icons/los_icon.dart diff --git a/lib/icons/los_icon.dart b/lib/icons/los_icon.dart new file mode 100644 index 0000000..86bef06 --- /dev/null +++ b/lib/icons/los_icon.dart @@ -0,0 +1,80 @@ +import 'dart:math' as math; + +import 'package:flutter/material.dart'; + +class LosIcon extends StatelessWidget { + final double size; + final Color? color; + + const LosIcon({ + super.key, + this.size = 24, + this.color, + }); + + @override + Widget build(BuildContext context) { + final iconColor = color ?? IconTheme.of(context).color ?? Colors.black; + final canvasSize = size; + + return SizedBox( + width: canvasSize, + height: canvasSize, + child: CustomPaint( + painter: _LosIconPainter(iconColor), + ), + ); + } +} + +class _LosIconPainter extends CustomPainter { + final Color color; + + _LosIconPainter(this.color); + + @override + void paint(Canvas canvas, Size size) { + final paint = Paint() + ..color = color + ..style = PaintingStyle.fill; + + final path = Path() + ..moveTo(82, -120) + ..relativeLineTo(258, -360) + ..relativeLineTo(202, 0) + ..relativeLineTo(298, -348) + ..relativeLineTo(0, 708) + ..lineTo(82, -120) + ..close() + ..moveTo(152, -353) + ..relativeLineTo(-64, -46) + ..relativeLineTo(172, -241) + ..relativeLineTo(202, 0) + ..relativeLineTo(188, -219) + ..relativeLineTo(60, 52) + ..relativeLineTo(-212, 247) + ..lineTo(300, -560) + ..lineTo(152, -353) + ..close() + ..moveTo(238, -200) + ..relativeLineTo(522, 0) + ..relativeLineTo(0, -412) + ..lineTo(578, -400) + ..lineTo(380, -400) + ..lineTo(238, -200) + ..close(); + + final scale = math.min(size.width, size.height) / 960; + + canvas.save(); + canvas.translate(0, 960); + canvas.scale(scale, scale); + canvas.drawPath(path, paint); + canvas.restore(); + } + + @override + bool shouldRepaint(covariant _LosIconPainter oldDelegate) { + return oldDelegate.color != color; + } +} diff --git a/lib/screens/line_of_sight_map_screen.dart b/lib/screens/line_of_sight_map_screen.dart index b073685..dfda1c1 100644 --- a/lib/screens/line_of_sight_map_screen.dart +++ b/lib/screens/line_of_sight_map_screen.dart @@ -16,6 +16,7 @@ import '../services/map_tile_cache_service.dart'; import '../utils/route_transitions.dart'; import '../widgets/app_bar.dart'; import '../widgets/quick_switch_bar.dart'; +import '../icons/los_icon.dart'; class LineOfSightEndpoint { final String label; @@ -642,7 +643,7 @@ class _LineOfSightMapScreenState extends State { alignment: Alignment.centerRight, child: ElevatedButton.icon( onPressed: _loading ? null : _runLos, - icon: const Icon(Icons.visibility), + icon: const LosIcon(), label: Text(context.l10n.losRun), ), ), diff --git a/lib/screens/map_screen.dart b/lib/screens/map_screen.dart index 77ec98c..b688a30 100644 --- a/lib/screens/map_screen.dart +++ b/lib/screens/map_screen.dart @@ -20,6 +20,7 @@ import '../services/map_tile_cache_service.dart'; import '../utils/contact_search.dart'; import '../utils/route_transitions.dart'; import '../widgets/quick_switch_bar.dart'; +import '../icons/los_icon.dart'; import 'channels_screen.dart'; import 'chat_screen.dart'; import 'contacts_screen.dart'; @@ -280,7 +281,7 @@ class _MapScreenState extends State { ), if (!_isBuildingPathTrace) IconButton( - icon: const Icon(Icons.visibility), + icon: const LosIcon(), onPressed: () { final candidates = []; if (connector.selfLatitude != null &&