Fix wind marker slack and off-center header bar

Zwei vom Nutzer per Screenshot gemeldete Probleme:

1. Der Wind-Marker auf der Karte liess bei kurzen Werten (z.B. "1 m/s")
   weiterhin sichtbaren Leerraum rechts neben dem Text - die letzte
   Anpassung hatte die Marker-Box auf den unguenstigsten Fall
   (zweistellig, "25 m/s") fixiert bemessen, wodurch einstellige Werte
   in derselben Box zu viel Platz hatten. flutter_map's Marker verlangt
   eine feste Breite (kein intrinsisches Sizing), also wird sie jetzt
   pro Wegpunkt aus der Ziffernzahl der Geschwindigkeit berechnet
   (+11px/Ziffer, per Widget-Messung ermittelt) statt eine einzelne
   Konstante fuer alle Faelle zu verwenden.

2. Die Kopfleiste sass nicht mittig, sondern wirkte nach rechts
   verschoben. Ursache: SafeArea wendet links/rechts die jeweils
   tatsaechlichen (auf diesem Emulator unterschiedlich grossen)
   Insets an - dadurch war der fuer FractionallySizedBox verfuegbare
   Bereich selbst schon asymmetrisch zur Bildschirmmitte verschoben.
   Ersetzt durch denselben symmetrischen Randabstand (max(links,
   rechts)), der in PlanScreen fuer die Drehraeder bereits etabliert ist.

Verifiziert: flutter analyze (0 issues), flutter test (64/64), manuell
auf Pixel_10a-Emulator - Kopfleiste jetzt sichtbar mittig, mehrere
Wind-Marker mit "1 m/s" zeigen keinen Leerraum mehr.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Constantin Leue
2026-07-28 15:53:42 +02:00
co-authored by Claude Sonnet 5
parent 926d805156
commit 5505bb3741
2 changed files with 37 additions and 3 deletions
+16 -1
View File
@@ -407,7 +407,7 @@ class _PlanScreenState extends ConsumerState<PlanScreen> {
if (wp.windSpeedMs != null && wp.windDirFromDeg != null)
Marker(
point: LatLng(wp.lat, wp.lon),
width: 102,
width: _windMarkerWidth(wp.windSpeedMs!),
height: 22,
alignment: const Alignment(1.1, -1.5),
child: WindMarkerPill(
@@ -558,4 +558,19 @@ class _PlanScreenState extends ConsumerState<PlanScreen> {
borderColor: Colors.white,
);
}
/// flutter_map's Marker verlangt eine feste Breite (kein intrinsisches
/// Sizing wie bei normalen Widgets) - eine einzelne fuer alle Faelle
/// grosszuegig bemessene Breite liesse bei kurzen Werten (z.B. "1 m/s")
/// sichtbaren Leerraum rechts neben dem Text. Stattdessen je Ziffernzahl
/// berechnet (per Widget-Messung ermittelt: +11px/Ziffer, siehe
/// WindMarkerPill).
double _windMarkerWidth(double speedMs) {
final digits = speedMs.round().abs().toString().length;
// +1px Puffer: MarkerLayer rendert ueber eine eigene Transform-/
// OverflowBox-Kette, die im echten Baum minimal (< 1px) anders rundet
// als eine isolierte Messung - ohne Puffer fuehrte das zu einem
// 0.25px-Overflow.
return 81.0 + digits * 11.0;
}
}
+21 -2
View File
@@ -1,3 +1,5 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -24,8 +26,25 @@ class TopModeBar extends StatelessWidget {
final isFly = context.select((AppModeCubit c) => c.state.mode == AppMode.fly);
final activeTint = isFly ? DmcColors.flyModeRed : DmcColors.editModeGreen;
return SafeArea(
bottom: false,
// Kein SafeArea: das wendet links/rechts die jeweils tatsaechlichen
// (oft asymmetrischen) Insets an, wodurch die Leiste sichtbar von der
// Bildschirmmitte abweicht, sobald eine Seite einen groesseren
// Aussparungsbereich meldet als die andere. Stattdessen derselbe
// symmetrische Randabstand wie bei den Drehraedern (PlanScreen:
// safeEdgeInset) - dadurch bleibt die per FractionallySizedBox
// zentrierte Leiste auch bei asymmetrischen Insets echt mittig.
final topInset = MediaQuery.of(context).padding.top;
final safeEdgeInset = math.max(
MediaQuery.of(context).padding.left,
MediaQuery.of(context).padding.right,
);
return Padding(
padding: EdgeInsets.only(
top: topInset,
left: safeEdgeInset,
right: safeEdgeInset,
),
child: FractionallySizedBox(
widthFactor: 0.70,
child: Container(