From 4485c1644e21a2a6a5ff08de0954fce4ee5ad39a Mon Sep 17 00:00:00 2001 From: Constantin Leue <77660791+Consti3D@users.noreply.github.com> Date: Fri, 7 Aug 2026 22:27:49 +0200 Subject: [PATCH] Fix mode-button gradient to fade via alpha instead of a color mix Interpolating RGB between activeTint and inactiveColor produced a visibly muddy intermediate color that read as a hard cut inside the button rather than a soft fade. Switched to a pure alpha gradient of inactiveColor itself (0.0 -> 0.85): at alpha 0 it exactly matches the header container's own tint sitting behind it, so the seam disappears entirely, and the color only ever mixes with itself. Also pushed the stop from 30% to 45% of the button's width for more breathing room before the solid fill starts. --- app/lib/ui/widgets/top_mode_bar.dart | 38 +++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/app/lib/ui/widgets/top_mode_bar.dart b/app/lib/ui/widgets/top_mode_bar.dart index 86586df..3026d97 100644 --- a/app/lib/ui/widgets/top_mode_bar.dart +++ b/app/lib/ui/widgets/top_mode_bar.dart @@ -46,8 +46,7 @@ class TopModeBar extends ConsumerWidget { /// Leistenkante (HTML-Demonstrator: `#topBarWrap{padding:5px 10px}`) - der /// inaktive Button verzichtet bewusst darauf, siehe Klassendoku oben. static const _outerPaddingH = 10.0; - // Halbiert (Nutzerwunsch: vertikaler Innenabstand noch zu gross) - der - // aktive Moduswechsel-Button und der mittlere Inhalt (Wind-Pille/ + // Der aktive Moduswechsel-Button und der mittlere Inhalt (Wind-Pille/ // Suchleiste/Flugmodus) bleiben oben/unten um diesen Betrag von der // Leistenkante eingerueckt, siehe Klassendoku. static const _outerPaddingV = 5.0; @@ -113,7 +112,6 @@ class TopModeBar extends ConsumerWidget { _ModeButton( label: 'Plan', isActive: !isFly, - activeTint: activeTint, inactiveColor: DmcColors.planModeColor, isLeftButton: true, onTap: () => context.read().toPlan(), @@ -132,7 +130,6 @@ class TopModeBar extends ConsumerWidget { _ModeButton( label: 'Fly', isActive: isFly, - activeTint: activeTint, inactiveColor: DmcColors.flyModeColor, isLeftButton: false, onTap: () { @@ -161,7 +158,6 @@ class _ModeButton extends StatelessWidget { const _ModeButton({ required this.label, required this.isActive, - required this.activeTint, required this.inactiveColor, required this.isLeftButton, required this.onTap, @@ -169,11 +165,6 @@ class _ModeButton extends StatelessWidget { final String label; final bool isActive; - - /// Aktuelle Kopfleisten-Toenung (TopModeBar.activeTint) - dient nur als - /// Startfarbe des Farbverlaufs im inaktiven Zustand (siehe unten), der - /// aktive Button hat ohnehin keinen eigenen Hintergrund. - final Color activeTint; final Color inactiveColor; /// true = Plan-Button (linkes Ende der Leiste), false = Fly-Button @@ -207,20 +198,31 @@ class _ModeButton extends StatelessWidget { decoration: isActive ? null : BoxDecoration( - // Kurzer Farbverlauf von der Kopfleisten-eigenen Toenung zur - // vollen Button-Farbe statt einer harten Kante an der - // Nahtstelle zum mittleren Inhalt (Nutzerwunsch: "linearer - // kurzer Farbverlauf zwischen button und rest header") - nur - // die ersten 30% der Breite blenden ein, der Rest bleibt - // solide, damit der Text weiterhin auf vollem Kontrast sitzt. + // Farbverlauf von der Kopfleisten-eigenen Toenung zur vollen + // Button-Farbe statt einer harten Kante an der Nahtstelle zum + // mittleren Inhalt (Nutzerwunsch: "linearer kurzer + // Farbverlauf zwischen button und rest header"). Reiner + // Alpha-Verlauf DERSELBEN inactiveColor (0.0 -> 0.85) statt + // einer RGB-Ueberblendung zwischen zwei verschiedenen Farben - + // Letzteres erzeugte einen sichtbar "verschmutzten" + // Zwischenton, der wie eine harte Kante mitten im Button + // wirkte, statt wie ein weiches Einblenden (Nutzer-Feedback: + // "der Verlauf schneidet in den Knopf rein"). Bei Alpha 0 + // liegt exakt die Toenung des umgebenden TopModeBar- + // Containers darunter (dieselbe activeTint-Farbe, derselbe + // Alpha-Wert 0.55, siehe dortige Decoration), der Uebergang + // an der Nahtstelle ist dadurch von selbst nahtlos. Stop bei + // 45% statt vorher 30% laesst mehr Abstand, bevor die + // Volltonflaeche des eigentlichen Knopfes beginnt (ebenfalls + // Nutzer-Feedback). gradient: LinearGradient( begin: isLeftButton ? Alignment.centerRight : Alignment.centerLeft, end: isLeftButton ? Alignment.centerLeft : Alignment.centerRight, colors: [ - activeTint.withValues(alpha: 0.55), + inactiveColor.withValues(alpha: 0.0), inactiveColor.withValues(alpha: 0.85), ], - stops: const [0.0, 0.3], + stops: const [0.0, 0.45], ), ), child: Text(