From 03c24b830e1c30fe3366b983eec56988f7ac304c Mon Sep 17 00:00:00 2001 From: Constantin Leue <77660791+Consti3D@users.noreply.github.com> Date: Fri, 7 Aug 2026 23:03:43 +0200 Subject: [PATCH] Drop the drone status panel's title bar, default the grid to 3 columns The title row cost a full line of vertical space for a redundant label. The close button now floats over the tab row instead, which reserves 48px on its right so "System Messages" doesn't sit under it. Also replaced the manually grouped 2/3-column row layout with uniform 3-per-row chunking of a flat field list, matching the user's request to default to three fields per row. --- .../widgets/drone_status_messages_panel.dart | 205 ++++++++---------- app/test/widget_test.dart | 3 +- 2 files changed, 96 insertions(+), 112 deletions(-) diff --git a/app/lib/ui/widgets/drone_status_messages_panel.dart b/app/lib/ui/widgets/drone_status_messages_panel.dart index 237570f..1fa1acc 100644 --- a/app/lib/ui/widgets/drone_status_messages_panel.dart +++ b/app/lib/ui/widgets/drone_status_messages_panel.dart @@ -38,41 +38,41 @@ class _DroneStatusMessagesPanelState extends ConsumerState Navigator.of(context).pop(), - icon: const Icon(Icons.close, color: Colors.white), - ), - ], - ), - ), - Row( + Column( children: [ - _tabButton('Status', _PanelTab.status), - _tabButton('System Messages', _PanelTab.messages), + Padding( + // Rechts Platz fuer den schwebenden Schliessen-Knopf, damit + // "System Messages" nicht darunter verschwindet. + padding: const EdgeInsets.only(right: 48), + child: Row( + children: [ + _tabButton('Status', _PanelTab.status), + _tabButton('System Messages', _PanelTab.messages), + ], + ), + ), + const Divider(color: Colors.white24, height: 1), + Expanded( + child: switch (_tab) { + _PanelTab.status => _statusTab(), + _PanelTab.messages => _messagesTab(), + }, + ), ], ), - const Divider(color: Colors.white24, height: 1), - Expanded( - child: switch (_tab) { - _PanelTab.status => _statusTab(), - _PanelTab.messages => _messagesTab(), - }, + Positioned( + top: 4, + right: 4, + child: IconButton( + onPressed: () => Navigator.of(context).pop(), + icon: const Icon(Icons.close, color: Colors.white), + ), ), ], ), @@ -144,97 +144,80 @@ class _DroneStatusMessagesPanelState extends ConsumerState _statusRows(List> rows) { - return [ - for (final tiles in rows) - Row( - children: [ - for (var i = 0; i < tiles.length; i++) ...[ - if (i > 0) const SizedBox(width: 8), - Expanded(child: tiles[i]), - ], + /// Ordnet die Statuszeilen zu je [perRow] pro Zeile an (Doku: "standardmaessig + /// drei felder pro zeile im drone status menue anzeigen") - bei einer nicht + /// durch [perRow] teilbaren Feldanzahl bleibt die letzte Zeile schmaler, + /// statt sie kuenstlich mit leeren Kacheln aufzufuellen. + List _statusRows(List tiles, {int perRow = 3}) { + final rows = []; + for (var i = 0; i < tiles.length; i += perRow) { + final chunk = tiles.skip(i).take(perRow).toList(); + rows.add(Row( + children: [ + for (var j = 0; j < chunk.length; j++) ...[ + if (j > 0) const SizedBox(width: 8), + Expanded(child: chunk[j]), ], - ), - ]; + ], + )); + } + return rows; } static const _signalColors = { diff --git a/app/test/widget_test.dart b/app/test/widget_test.dart index 8a88856..9cdd73b 100644 --- a/app/test/widget_test.dart +++ b/app/test/widget_test.dart @@ -30,6 +30,7 @@ import 'package:dmc_app/ui/providers/system_message_log_provider.dart'; import 'package:dmc_app/ui/providers/telemetry_provider.dart'; import 'package:dmc_app/transport/mock/mock_flight_controller_link.dart'; import 'package:dmc_app/ui/widgets/drone_follow_icon.dart'; +import 'package:dmc_app/ui/widgets/drone_status_messages_panel.dart'; import 'package:dmc_app/ui/widgets/full_value_chart.dart'; import 'package:dmc_app/ui/widgets/halo_menu.dart'; import 'package:dmc_app/ui/widgets/header_wind_pill.dart'; @@ -1160,7 +1161,7 @@ void main() { // steht im Widget-Baum zuerst. await tester.tap(find.byType(PaperPlaneIcon).first); await tester.pumpAndSettle(); - expect(find.text('Drone Status & System Messages'), findsOneWidget); + expect(find.byType(DroneStatusMessagesPanel), findsOneWidget); await tester.tap(find.text('System Messages')); await tester.pumpAndSettle();