From 3e05770bfcb74840aa58bd1843dc75d809c7ee41 Mon Sep 17 00:00:00 2001 From: Gold87 Date: Sun, 26 May 2024 15:55:05 -0400 Subject: [PATCH 1/4] Initial separation of tab grid widget and state --- lib/pages/dashboard_page.dart | 45 +++---- .../draggable_widget_container.dart | 2 +- .../models/list_layout_model.dart | 2 +- lib/widgets/editable_tab_bar.dart | 10 +- lib/widgets/tab_grid.dart | 120 +++++++++--------- test/widgets/editable_tab_bar_test.dart | 24 ++-- test/widgets/tab_grid_test.dart | 26 ++-- 7 files changed, 107 insertions(+), 122 deletions(-) diff --git a/lib/pages/dashboard_page.dart b/lib/pages/dashboard_page.dart index 088770d3..45db11e0 100644 --- a/lib/pages/dashboard_page.dart +++ b/lib/pages/dashboard_page.dart @@ -55,7 +55,7 @@ class _DashboardPageState extends State with WindowListener { late final SharedPreferences preferences = widget.preferences; late final UpdateChecker _updateChecker; - final List _grids = []; + final List _grids = []; final List _tabData = []; @@ -111,7 +111,7 @@ class _DashboardPageState extends State with WindowListener { widget.ntConnection.addConnectedListener(() { setState(() { - for (TabGrid grid in _grids) { + for (TabGridModel grid in _grids) { grid.onNTConnect(); } }); @@ -119,7 +119,7 @@ class _DashboardPageState extends State with WindowListener { widget.ntConnection.addDisconnectedListener(() { setState(() { - for (TabGrid grid in _grids) { + for (TabGridModel grid in _grids) { grid.onNTDisconnect(); } }); @@ -166,8 +166,7 @@ class _DashboardPageState extends State with WindowListener { _tabData.add(TabData(name: tab)); _grids.add( - TabGrid( - key: GlobalKey(), + TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, @@ -191,8 +190,7 @@ class _DashboardPageState extends State with WindowListener { if (!tabNamesList.contains(tabName)) { _tabData.add(TabData(name: tabName)); - _grids.add(TabGrid( - key: GlobalKey(), + _grids.add(TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, @@ -253,7 +251,7 @@ class _DashboardPageState extends State with WindowListener { for (int i = 0; i < _tabData.length; i++) { TabData data = _tabData[i]; - TabGrid grid = _grids[i]; + TabGridModel grid = _grids[i]; gridData.add({ 'name': data.name, @@ -574,8 +572,7 @@ class _DashboardPageState extends State with WindowListener { _tabData.add(TabData(name: data['name'])); _grids.add( - TabGrid.fromJson( - key: GlobalKey(), + TabGridModel.fromJson( ntConnection: widget.ntConnection, preferences: widget.preferences, jsonData: data['grid_layout'], @@ -602,14 +599,12 @@ class _DashboardPageState extends State with WindowListener { ]); _grids.addAll([ - TabGrid( - key: GlobalKey(), + TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, ), - TabGrid( - key: GlobalKey(), + TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, @@ -760,8 +755,7 @@ class _DashboardPageState extends State with WindowListener { _tabData.add(TabData(name: newTabName)); _grids.add( - TabGrid( - key: GlobalKey(), + TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, @@ -807,14 +801,14 @@ class _DashboardPageState extends State with WindowListener { } void _lockLayout() async { - for (TabGrid grid in _grids) { + for (TabGridModel grid in _grids) { grid.lockLayout(); } await preferences.setBool(PrefKeys.layoutLocked, true); } void _unlockLayout() async { - for (TabGrid grid in _grids) { + for (TabGridModel grid in _grids) { grid.unlockLayout(); } await preferences.setBool(PrefKeys.layoutLocked, false); @@ -1026,7 +1020,7 @@ class _DashboardPageState extends State with WindowListener { await preferences.setInt(PrefKeys.gridSize, newGridSize); - for (TabGrid grid in _grids) { + for (TabGridModel grid in _grids) { grid.resizeGrid(_gridSize, _gridSize); } }, @@ -1045,7 +1039,7 @@ class _DashboardPageState extends State with WindowListener { await preferences.setDouble(PrefKeys.cornerRadius, newRadius); setState(() { - for (TabGrid grid in _grids) { + for (TabGridModel grid in _grids) { grid.refreshAllContainers(); } }); @@ -1235,7 +1229,7 @@ class _DashboardPageState extends State with WindowListener { _tabData[_currentTabIndex] = tempData; // Swap the tab grids - TabGrid tempGrid = _grids[_currentTabIndex - 1]; + TabGridModel tempGrid = _grids[_currentTabIndex - 1]; _grids[_currentTabIndex - 1] = _grids[_currentTabIndex]; _grids[_currentTabIndex] = tempGrid; @@ -1262,7 +1256,7 @@ class _DashboardPageState extends State with WindowListener { _tabData[_currentTabIndex] = tempData; // Swap the tab grids - TabGrid tempGrid = _grids[_currentTabIndex + 1]; + TabGridModel tempGrid = _grids[_currentTabIndex + 1]; _grids[_currentTabIndex + 1] = _grids[_currentTabIndex]; _grids[_currentTabIndex] = tempGrid; @@ -1492,8 +1486,7 @@ class _DashboardPageState extends State with WindowListener { onTabCreate: (tab) { setState(() { _tabData.add(tab); - _grids.add(TabGrid( - key: GlobalKey(), + _grids.add(TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, @@ -1611,7 +1604,7 @@ class _DashboardPageState extends State with WindowListener { class _AddWidgetDialog extends StatefulWidget { final NTConnection ntConnection; final SharedPreferences preferences; - final TabGrid Function() _grid; + final TabGridModel Function() _grid; final bool _visible; final Function(Offset globalPosition, WidgetContainerModel widget) @@ -1627,7 +1620,7 @@ class _AddWidgetDialog extends StatefulWidget { const _AddWidgetDialog({ required this.ntConnection, required this.preferences, - required TabGrid Function() grid, + required TabGridModel Function() grid, required bool visible, required dynamic Function(Offset, WidgetContainerModel) onNTDragUpdate, required dynamic Function(WidgetContainerModel) onNTDragEnd, diff --git a/lib/widgets/draggable_containers/draggable_widget_container.dart b/lib/widgets/draggable_containers/draggable_widget_container.dart index df4016a4..1add45a1 100644 --- a/lib/widgets/draggable_containers/draggable_widget_container.dart +++ b/lib/widgets/draggable_containers/draggable_widget_container.dart @@ -8,7 +8,7 @@ import 'package:elastic_dashboard/widgets/tab_grid.dart'; import 'models/widget_container_model.dart'; class DraggableWidgetContainer extends StatelessWidget { - final TabGrid tabGrid; + final TabGridModel tabGrid; final Function( WidgetContainerModel widget, Rect newRect, TransformResult result)? diff --git a/lib/widgets/draggable_containers/models/list_layout_model.dart b/lib/widgets/draggable_containers/models/list_layout_model.dart index cb1eefe4..0b6eb144 100644 --- a/lib/widgets/draggable_containers/models/list_layout_model.dart +++ b/lib/widgets/draggable_containers/models/list_layout_model.dart @@ -27,7 +27,7 @@ class ListLayoutModel extends LayoutContainerModel { String labelPosition = 'TOP'; final NTConnection ntConnection; - final TabGrid tabGrid; + final TabGridModel tabGrid; final Function(WidgetContainerModel model)? onDragCancel; static List labelPositions = const [ diff --git a/lib/widgets/editable_tab_bar.dart b/lib/widgets/editable_tab_bar.dart index 83d2f648..6f9d7b1d 100644 --- a/lib/widgets/editable_tab_bar.dart +++ b/lib/widgets/editable_tab_bar.dart @@ -19,7 +19,7 @@ class TabData { class EditableTabBar extends StatelessWidget { final SharedPreferences preferences; - final List tabViews; + final List tabViews; final List tabData; final Function(TabData tab) onTabCreate; @@ -291,10 +291,10 @@ class EditableTabBar extends StatelessWidget { curve: Curves.decelerate, index: currentIndex, children: [ - for (TabGrid grid in tabViews) - ChangeNotifierProvider( - create: (context) => TabGridModel(), - child: grid, + for (TabGridModel grid in tabViews) + ChangeNotifierProvider.value( + value: grid, + child: const TabGrid(), ), ], ), diff --git a/lib/widgets/tab_grid.dart b/lib/widgets/tab_grid.dart index 61404920..f5c2d259 100644 --- a/lib/widgets/tab_grid.dart +++ b/lib/widgets/tab_grid.dart @@ -22,30 +22,21 @@ import 'draggable_containers/models/widget_container_model.dart'; // Used to refresh the tab grid when a widget is added or removed // This doesn't use a stateful widget since everything has to be rendered at program startup or data will be lost class TabGridModel extends ChangeNotifier { - void notify() { - notifyListeners(); - } -} - -class TabGrid extends StatelessWidget { final NTConnection ntConnection; final SharedPreferences preferences; final List _widgetModels = []; MapEntry? _containerDraggingIn; + BuildContext? tabGridContext; final VoidCallback onAddWidgetPressed; - TabGridModel? model; - - TabGrid( - {super.key, - required this.ntConnection, + TabGridModel( + {required this.ntConnection, required this.preferences, required this.onAddWidgetPressed}); - TabGrid.fromJson({ - super.key, + TabGridModel.fromJson({ required this.ntConnection, required this.preferences, required Map jsonData, @@ -127,13 +118,12 @@ class TabGrid extends StatelessWidget { } Offset getLocalPosition(Offset globalPosition) { - BuildContext? context = (key as GlobalKey).currentContext; - - if (context == null) { + if (tabGridContext == null) { return Offset.zero; } - RenderBox? ancestor = context.findAncestorRenderObjectOfType(); + RenderBox? ancestor = + tabGridContext!.findAncestorRenderObjectOfType(); Offset localPosition = ancestor!.globalToLocal(globalPosition); @@ -156,10 +146,9 @@ class TabGrid extends StatelessWidget { /// /// This only applies to widgets that already have a place on the grid bool isValidMoveLocation(WidgetContainerModel widget, Rect location) { - BuildContext? context = (key as GlobalKey).currentContext; Size? gridSize; - if (context != null) { - gridSize = MediaQuery.of(context).size; + if (tabGridContext != null) { + gridSize = MediaQuery.of(tabGridContext!).size; } for (WidgetContainerModel container in _widgetModels) { @@ -692,12 +681,6 @@ class TabGrid extends StatelessWidget { _widgetModels.clear(); } - void refresh() { - Future(() async { - model?.notify(); - }); - } - void resizeGrid(int oldSize, int newSize) { for (WidgetContainerModel widget in _widgetModels) { widget.updateGridSize(oldSize, newSize); @@ -713,37 +696,47 @@ class TabGrid extends StatelessWidget { }); } + void refresh() { + notifyListeners(); + } +} + +class TabGrid extends StatelessWidget { + const TabGrid({super.key}); + @override Widget build(BuildContext context) { - model = context.watch(); + TabGridModel model = context.watch(); - Widget getWidgetFromModel(WidgetContainerModel model) { - if (model is NTWidgetContainerModel) { + model.tabGridContext = context; + + Widget getWidgetFromModel(WidgetContainerModel widgetModel) { + if (widgetModel is NTWidgetContainerModel) { return ChangeNotifierProvider.value( - value: model, + value: widgetModel, child: DraggableNTWidgetContainer( - key: model.key, - tabGrid: this, - onUpdate: _ntContainerOnUpdate, - onDragBegin: _ntContainerOnDragBegin, - onDragEnd: _ntContainerOnDragEnd, - onDragCancel: _ntContainerOnDragCancel, - onResizeBegin: _ntContainerOnResizeBegin, - onResizeEnd: _ntContainerOnResizeEnd, + key: widgetModel.key, + tabGrid: model, + onUpdate: model._ntContainerOnUpdate, + onDragBegin: model._ntContainerOnDragBegin, + onDragEnd: model._ntContainerOnDragEnd, + onDragCancel: model._ntContainerOnDragCancel, + onResizeBegin: model._ntContainerOnResizeBegin, + onResizeEnd: model._ntContainerOnResizeEnd, ), ); - } else if (model is ListLayoutModel) { + } else if (widgetModel is ListLayoutModel) { return ChangeNotifierProvider.value( - value: model, + value: widgetModel, child: DraggableListLayout( - key: model.key, - tabGrid: this, - onUpdate: _layoutContainerOnUpdate, - onDragBegin: _layoutContainerOnDragBegin, - onDragEnd: _layoutContainerOnDragEnd, - onDragCancel: _layoutContainerOnDragCancel, - onResizeBegin: _layoutContainerOnResizeBegin, - onResizeEnd: _layoutContainerOnResizeEnd, + key: widgetModel.key, + tabGrid: model, + onUpdate: model._layoutContainerOnUpdate, + onDragBegin: model._layoutContainerOnDragBegin, + onDragEnd: model._layoutContainerOnDragEnd, + onDragCancel: model._layoutContainerOnDragCancel, + onResizeBegin: model._layoutContainerOnResizeBegin, + onResizeEnd: model._layoutContainerOnResizeEnd, ), ); } @@ -755,7 +748,7 @@ class TabGrid extends StatelessWidget { List draggingInWidgets = []; List previewOutlines = []; - for (WidgetContainerModel container in _widgetModels) { + for (WidgetContainerModel container in model._widgetModels) { if (container.dragging) { draggingWidgets.add( Positioned( @@ -773,7 +766,7 @@ class TabGrid extends StatelessWidget { ); } else { LayoutContainerModel? layoutContainer = - getLayoutAtLocation(container.cursorGlobalLocation); + model.getLayoutAtLocation(container.cursorGlobalLocation); if (layoutContainer == null) { previewOutlines.add( @@ -792,7 +785,7 @@ class TabGrid extends StatelessWidget { decoration: BoxDecoration( color: Colors.white.withOpacity(0.25), borderRadius: BorderRadius.circular( - preferences.getDouble(PrefKeys.cornerRadius) ?? + model.preferences.getDouble(PrefKeys.cornerRadius) ?? Defaults.cornerRadius), border: Border.all(color: Colors.yellow, width: 5.0), ), @@ -808,7 +801,7 @@ class TabGrid extends StatelessWidget { GestureDetector( onTap: () {}, onSecondaryTapUp: (details) { - if (preferences.getBool(PrefKeys.layoutLocked) ?? + if (model.preferences.getBool(PrefKeys.layoutLocked) ?? Defaults.layoutLocked) { return; } @@ -830,7 +823,7 @@ class TabGrid extends StatelessWidget { label: 'Remove', icon: Icons.delete_outlined, onSelected: () { - removeWidget(container); + model.removeWidget(container); }), ]; @@ -861,8 +854,8 @@ class TabGrid extends StatelessWidget { } // Also render any containers that are being dragged into the grid - if (_containerDraggingIn != null) { - WidgetContainerModel container = _containerDraggingIn!.key; + if (model._containerDraggingIn != null) { + WidgetContainerModel container = model._containerDraggingIn!.key; draggingWidgets.add( Positioned( @@ -882,15 +875,16 @@ class TabGrid extends StatelessWidget { Rect previewLocation = Rect.fromLTWH(previewX, previewY, container.displayRect.width, container.displayRect.height); - bool validLocation = isValidMoveLocation(container, previewLocation) || - isValidLayoutLocation(container.cursorGlobalLocation); + bool validLocation = + model.isValidMoveLocation(container, previewLocation) || + model.isValidLayoutLocation(container.cursorGlobalLocation); Color borderColor = (validLocation) ? Colors.lightGreenAccent.shade400 : Colors.red; - if (isValidLayoutLocation(container.cursorGlobalLocation)) { + if (model.isValidLayoutLocation(container.cursorGlobalLocation)) { LayoutContainerModel layoutContainer = - getLayoutAtLocation(container.cursorGlobalLocation)!; + model.getLayoutAtLocation(container.cursorGlobalLocation)!; previewLocation = layoutContainer.displayRect; @@ -909,7 +903,7 @@ class TabGrid extends StatelessWidget { ? Colors.white.withOpacity(0.25) : Colors.black.withOpacity(0.1), borderRadius: BorderRadius.circular( - preferences.getDouble(PrefKeys.cornerRadius) ?? + model.preferences.getDouble(PrefKeys.cornerRadius) ?? Defaults.cornerRadius), border: Border.all(color: borderColor, width: 5.0), ), @@ -922,7 +916,7 @@ class TabGrid extends StatelessWidget { behavior: HitTestBehavior.translucent, onTap: () {}, onSecondaryTapUp: (details) { - if (preferences.getBool(PrefKeys.layoutLocked) ?? + if (model.preferences.getBool(PrefKeys.layoutLocked) ?? Defaults.layoutLocked) { return; } @@ -934,12 +928,12 @@ class TabGrid extends StatelessWidget { MenuItem( label: 'Add Widget', icon: Icons.add, - onSelected: () => onAddWidgetPressed.call(), + onSelected: () => model.onAddWidgetPressed.call(), ), MenuItem( label: 'Clear Layout', icon: Icons.clear, - onSelected: () => clearWidgets(context), + onSelected: () => model.clearWidgets(context), ), ], ); diff --git a/test/widgets/editable_tab_bar_test.dart b/test/widgets/editable_tab_bar_test.dart index f60879aa..ba8f672e 100644 --- a/test/widgets/editable_tab_bar_test.dart +++ b/test/widgets/editable_tab_bar_test.dart @@ -54,12 +54,12 @@ void main() { TabData(name: 'Autonomous'), ], tabViews: [ - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, ), - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, @@ -103,12 +103,12 @@ void main() { TabData(name: 'Autonomous'), ], tabViews: [ - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, ), - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, @@ -163,12 +163,12 @@ void main() { TabData(name: 'Autonomous'), ], tabViews: [ - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, ), - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, @@ -223,12 +223,12 @@ void main() { TabData(name: 'Autonomous'), ], tabViews: [ - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, ), - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, @@ -296,12 +296,12 @@ void main() { TabData(name: 'Autonomous'), ], tabViews: [ - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, ), - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, @@ -380,12 +380,12 @@ void main() { TabData(name: 'Autonomous'), ], tabViews: [ - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, ), - TabGrid( + TabGridModel( ntConnection: mockNTConnection, preferences: preferences, onAddWidgetPressed: () {}, diff --git a/test/widgets/tab_grid_test.dart b/test/widgets/tab_grid_test.dart index b25c7b8b..cfc7fe6d 100644 --- a/test/widgets/tab_grid_test.dart +++ b/test/widgets/tab_grid_test.dart @@ -77,14 +77,14 @@ void main() async { await widgetTester.pumpWidget( MaterialApp( home: Scaffold( - body: ChangeNotifierProvider( - create: (context) => TabGridModel(), - child: TabGrid.fromJson( + body: ChangeNotifierProvider.value( + value: TabGridModel.fromJson( ntConnection: createMockOfflineNT4(), preferences: preferences, jsonData: jsonData['tabs'][0]['grid_layout'], onAddWidgetPressed: () {}, ), + child: const TabGrid(), ), ), ), @@ -126,14 +126,14 @@ void main() async { await widgetTester.pumpWidget( MaterialApp( home: Scaffold( - body: ChangeNotifierProvider( - create: (context) => TabGridModel(), - child: TabGrid.fromJson( + body: ChangeNotifierProvider.value( + value: TabGridModel.fromJson( ntConnection: createMockOfflineNT4(), preferences: preferences, jsonData: jsonData['tabs'][1]['grid_layout'], onAddWidgetPressed: () {}, ), + child: const TabGrid(), ), ), ), @@ -168,15 +168,14 @@ void main() async { await widgetTester.pumpWidget( MaterialApp( home: Scaffold( - body: ChangeNotifierProvider( - create: (context) => TabGridModel(), - child: TabGrid.fromJson( - key: GlobalKey(), + body: ChangeNotifierProvider.value( + value: TabGridModel.fromJson( ntConnection: createMockOfflineNT4(), preferences: preferences, jsonData: jsonData['tabs'][0]['grid_layout'], onAddWidgetPressed: () {}, ), + child: const TabGrid(), ), ), ), @@ -246,15 +245,14 @@ void main() async { await widgetTester.pumpWidget( MaterialApp( home: Scaffold( - body: ChangeNotifierProvider( - create: (context) => TabGridModel(), - child: TabGrid.fromJson( - key: GlobalKey(), + body: ChangeNotifierProvider.value( + value: TabGridModel.fromJson( ntConnection: createMockOfflineNT4(), preferences: preferences, jsonData: jsonData['tabs'][0]['grid_layout'], onAddWidgetPressed: () {}, ), + child: const TabGrid(), ), ), ), From ff1fd647af8e855ef3ef87613d8a0a5ed82633a8 Mon Sep 17 00:00:00 2001 From: Gold87 Date: Mon, 27 May 2024 13:34:12 -0400 Subject: [PATCH 2/4] Remove tab grid dependency from draggable container model --- .../draggable_layout_container.dart | 8 +-- .../draggable_list_layout.dart | 8 +-- .../draggable_nt_widget_container.dart | 8 +-- .../draggable_widget_container.dart | 55 +++++++++---------- lib/widgets/tab_grid.dart | 32 ++++++----- 5 files changed, 47 insertions(+), 64 deletions(-) diff --git a/lib/widgets/draggable_containers/draggable_layout_container.dart b/lib/widgets/draggable_containers/draggable_layout_container.dart index 0bfa1064..13e13008 100644 --- a/lib/widgets/draggable_containers/draggable_layout_container.dart +++ b/lib/widgets/draggable_containers/draggable_layout_container.dart @@ -3,12 +3,6 @@ import 'package:elastic_dashboard/widgets/draggable_containers/draggable_widget_ abstract class DraggableLayoutContainer extends DraggableWidgetContainer { const DraggableLayoutContainer({ super.key, - required super.tabGrid, - super.onUpdate, - super.onDragBegin, - super.onDragEnd, - super.onDragCancel, - super.onResizeBegin, - super.onResizeEnd, + super.updateFunctions, }) : super(); } diff --git a/lib/widgets/draggable_containers/draggable_list_layout.dart b/lib/widgets/draggable_containers/draggable_list_layout.dart index 41e6db90..a1725666 100644 --- a/lib/widgets/draggable_containers/draggable_list_layout.dart +++ b/lib/widgets/draggable_containers/draggable_list_layout.dart @@ -8,13 +8,7 @@ import 'models/list_layout_model.dart'; class DraggableListLayout extends DraggableLayoutContainer { const DraggableListLayout({ super.key, - required super.tabGrid, - super.onUpdate, - super.onDragBegin, - super.onDragEnd, - super.onDragCancel, - super.onResizeBegin, - super.onResizeEnd, + super.updateFunctions, }) : super(); @override diff --git a/lib/widgets/draggable_containers/draggable_nt_widget_container.dart b/lib/widgets/draggable_containers/draggable_nt_widget_container.dart index ec850baa..00b6c910 100644 --- a/lib/widgets/draggable_containers/draggable_nt_widget_container.dart +++ b/lib/widgets/draggable_containers/draggable_nt_widget_container.dart @@ -8,13 +8,7 @@ import 'models/nt_widget_container_model.dart'; class DraggableNTWidgetContainer extends DraggableWidgetContainer { const DraggableNTWidgetContainer({ super.key, - required super.tabGrid, - super.onUpdate, - super.onDragBegin, - super.onDragEnd, - super.onDragCancel, - super.onResizeBegin, - super.onResizeEnd, + super.updateFunctions, }) : super(); @override diff --git a/lib/widgets/draggable_containers/draggable_widget_container.dart b/lib/widgets/draggable_containers/draggable_widget_container.dart index 1add45a1..cbfb5446 100644 --- a/lib/widgets/draggable_containers/draggable_widget_container.dart +++ b/lib/widgets/draggable_containers/draggable_widget_container.dart @@ -4,31 +4,26 @@ import 'package:flutter_box_transform/flutter_box_transform.dart'; import 'package:provider/provider.dart'; import 'package:elastic_dashboard/services/settings.dart'; -import 'package:elastic_dashboard/widgets/tab_grid.dart'; import 'models/widget_container_model.dart'; +typedef DraggableContainerUpdateFunctions = ({ + Function(WidgetContainerModel widget, Rect newRect, + TransformResult result) onUpdate, + Function(WidgetContainerModel widget) onDragBegin, + Function(WidgetContainerModel widget, Rect releaseRect, + {Offset? globalPosition}) onDragEnd, + Function(WidgetContainerModel widget) onDragCancel, + Function(WidgetContainerModel widget) onResizeBegin, + Function(WidgetContainerModel widget, Rect releaseRect) onResizeEnd, + bool Function(WidgetContainerModel widget, Rect location) isValidMoveLocation, +}); + class DraggableWidgetContainer extends StatelessWidget { - final TabGridModel tabGrid; - - final Function( - WidgetContainerModel widget, Rect newRect, TransformResult result)? - onUpdate; - final Function(WidgetContainerModel widget)? onDragBegin; - final Function(WidgetContainerModel widget, Rect releaseRect, - {Offset? globalPosition})? onDragEnd; - final Function(WidgetContainerModel widget)? onDragCancel; - final Function(WidgetContainerModel widget)? onResizeBegin; - final Function(WidgetContainerModel widget, Rect releaseRect)? onResizeEnd; + final DraggableContainerUpdateFunctions? updateFunctions; const DraggableWidgetContainer({ super.key, - required this.tabGrid, - this.onUpdate, - this.onDragBegin, - this.onDragEnd, - this.onDragCancel, - this.onResizeBegin, - this.onResizeEnd, + this.updateFunctions, }); static double snapToGrid(double value, [double? gridSize]) { @@ -65,9 +60,10 @@ class DraggableWidgetContainer extends StatelessWidget { model.setDragStartLocation(model.displayRect); model.setPreviewRect(model.dragStartLocation); model.setValidLocation( - tabGrid.isValidMoveLocation(model, model.previewRect)); + updateFunctions?.isValidMoveLocation(model, model.previewRect) ?? + true); - onDragBegin?.call(model); + updateFunctions?.onDragBegin(model); controller?.setRect(model.draggingRect); }, @@ -79,21 +75,22 @@ class DraggableWidgetContainer extends StatelessWidget { model.setDragStartLocation(model.displayRect); model.setPreviewRect(model.dragStartLocation); model.setValidLocation( - tabGrid.isValidMoveLocation(model, model.previewRect)); + updateFunctions?.isValidMoveLocation(model, model.previewRect) ?? + true); - onResizeBegin?.call(model); + updateFunctions?.onResizeBegin.call(model); controller?.setRect(model.draggingRect); }, onChanged: (result, event) { if (!model.dragging && !model.resizing) { - onDragCancel?.call(model); + updateFunctions?.onDragCancel(model); return; } model.setCursorGlobalLocation(event.globalPosition); - onUpdate?.call(model, result.rect, result); + updateFunctions?.onUpdate(model, result.rect, result); controller?.setRect(model.draggingRect); }, @@ -103,7 +100,7 @@ class DraggableWidgetContainer extends StatelessWidget { } model.setDragging(false); - onDragEnd?.call(model, model.draggingRect, + updateFunctions?.onDragEnd(model, model.draggingRect, globalPosition: model.cursorGlobalLocation); controller?.setRect(model.draggingRect); @@ -113,7 +110,7 @@ class DraggableWidgetContainer extends StatelessWidget { model.setDragging(false); }); - onDragCancel?.call(model); + updateFunctions?.onDragCancel(model); controller?.setRect(model.draggingRect); }, @@ -124,7 +121,7 @@ class DraggableWidgetContainer extends StatelessWidget { model.setDragging(false); model.setResizing(false); - onResizeEnd?.call(model, model.draggingRect); + updateFunctions?.onResizeEnd(model, model.draggingRect); controller?.setRect(model.draggingRect); }, @@ -132,7 +129,7 @@ class DraggableWidgetContainer extends StatelessWidget { model.setDragging(false); model.setResizing(false); - onDragCancel?.call(model); + updateFunctions?.onDragCancel(model); controller?.setRect(model.draggingRect); }, diff --git a/lib/widgets/tab_grid.dart b/lib/widgets/tab_grid.dart index f5c2d259..2372c8f0 100644 --- a/lib/widgets/tab_grid.dart +++ b/lib/widgets/tab_grid.dart @@ -716,13 +716,15 @@ class TabGrid extends StatelessWidget { value: widgetModel, child: DraggableNTWidgetContainer( key: widgetModel.key, - tabGrid: model, - onUpdate: model._ntContainerOnUpdate, - onDragBegin: model._ntContainerOnDragBegin, - onDragEnd: model._ntContainerOnDragEnd, - onDragCancel: model._ntContainerOnDragCancel, - onResizeBegin: model._ntContainerOnResizeBegin, - onResizeEnd: model._ntContainerOnResizeEnd, + updateFunctions: ( + onUpdate: model._ntContainerOnUpdate, + onDragBegin: model._ntContainerOnDragBegin, + onDragEnd: model._ntContainerOnDragEnd, + onDragCancel: model._ntContainerOnDragCancel, + onResizeBegin: model._ntContainerOnResizeBegin, + onResizeEnd: model._ntContainerOnResizeEnd, + isValidMoveLocation: model.isValidMoveLocation, + ), ), ); } else if (widgetModel is ListLayoutModel) { @@ -730,13 +732,15 @@ class TabGrid extends StatelessWidget { value: widgetModel, child: DraggableListLayout( key: widgetModel.key, - tabGrid: model, - onUpdate: model._layoutContainerOnUpdate, - onDragBegin: model._layoutContainerOnDragBegin, - onDragEnd: model._layoutContainerOnDragEnd, - onDragCancel: model._layoutContainerOnDragCancel, - onResizeBegin: model._layoutContainerOnResizeBegin, - onResizeEnd: model._layoutContainerOnResizeEnd, + updateFunctions: ( + onUpdate: model._layoutContainerOnUpdate, + onDragBegin: model._layoutContainerOnDragBegin, + onDragEnd: model._layoutContainerOnDragEnd, + onDragCancel: model._layoutContainerOnDragCancel, + onResizeBegin: model._layoutContainerOnResizeBegin, + onResizeEnd: model._layoutContainerOnResizeEnd, + isValidMoveLocation: model.isValidMoveLocation, + ), ), ); } From 6a036519c19ebced605ded6130b87ceaafd4a404 Mon Sep 17 00:00:00 2001 From: Gold87 Date: Sun, 9 Jun 2024 16:40:59 -0400 Subject: [PATCH 3/4] Removed ntConnection dependency from list layout --- .../models/list_layout_model.dart | 30 +++++++++++-------- lib/widgets/tab_grid.dart | 19 ++++++++++-- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/lib/widgets/draggable_containers/models/list_layout_model.dart b/lib/widgets/draggable_containers/models/list_layout_model.dart index 0b6eb144..9ee32ae6 100644 --- a/lib/widgets/draggable_containers/models/list_layout_model.dart +++ b/lib/widgets/draggable_containers/models/list_layout_model.dart @@ -6,8 +6,8 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; import 'package:dot_cast/dot_cast.dart'; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; -import 'package:elastic_dashboard/services/nt_connection.dart'; import 'package:elastic_dashboard/services/settings.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/dialog_dropdown_chooser.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/dialog_text_input.dart'; @@ -26,8 +26,14 @@ class ListLayoutModel extends LayoutContainerModel { String labelPosition = 'TOP'; - final NTConnection ntConnection; final TabGridModel tabGrid; + final NTWidgetContainerModel? Function( + SharedPreferences preferences, + Map jsonData, + bool enabled, { + Function(String errorMessage)? onJsonLoadingWarning, + })? ntWidgetBuilder; + final Function(WidgetContainerModel model)? onDragCancel; static List labelPositions = const [ @@ -42,9 +48,9 @@ class ListLayoutModel extends LayoutContainerModel { required super.preferences, required super.initialPosition, required super.title, - required this.ntConnection, required this.tabGrid, required this.onDragCancel, + this.ntWidgetBuilder, List? children, super.minWidth, super.minHeight, @@ -58,7 +64,7 @@ class ListLayoutModel extends LayoutContainerModel { ListLayoutModel.fromJson({ required super.jsonData, required super.preferences, - required this.ntConnection, + required this.ntWidgetBuilder, required this.tabGrid, required this.onDragCancel, super.enabled, @@ -125,15 +131,13 @@ class ListLayoutModel extends LayoutContainerModel { } for (Map childData in jsonData['children']) { - children.add( - NTWidgetContainerModel.fromJson( - ntConnection: ntConnection, - preferences: preferences, - jsonData: childData, - enabled: enabled, - onJsonLoadingWarning: onJsonLoadingWarning, - ), - ); + NTWidgetContainerModel? widgetModel = ntWidgetBuilder!( + preferences, childData, enabled, + onJsonLoadingWarning: onJsonLoadingWarning); + + if (widgetModel != null) { + children.add(widgetModel); + } } } diff --git a/lib/widgets/tab_grid.dart b/lib/widgets/tab_grid.dart index 2372c8f0..5d5472e2 100644 --- a/lib/widgets/tab_grid.dart +++ b/lib/widgets/tab_grid.dart @@ -82,9 +82,16 @@ class TabGridModel extends ChangeNotifier { switch (layoutData['type']) { case 'List Layout': widget = ListLayoutModel.fromJson( - ntConnection: ntConnection, preferences: preferences, jsonData: layoutData, + ntWidgetBuilder: (preferences, jsonData, enabled, + {onJsonLoadingWarning}) => + NTWidgetContainerModel.fromJson( + ntConnection: ntConnection, + jsonData: jsonData, + preferences: preferences, + onJsonLoadingWarning: onJsonLoadingWarning, + ), enabled: ntConnection.isNT4Connected, tabGrid: this, onDragCancel: _layoutContainerOnDragCancel, @@ -525,7 +532,6 @@ class TabGridModel extends ChangeNotifier { ListLayoutModel createListLayout( {String title = 'List Layout', List? children}) { return ListLayoutModel( - ntConnection: ntConnection, preferences: preferences, title: title, initialPosition: Rect.fromLTWH( @@ -593,9 +599,16 @@ class TabGridModel extends ChangeNotifier { case 'List Layout': _widgetModels.add( ListLayoutModel.fromJson( - ntConnection: ntConnection, preferences: preferences, jsonData: widgetData, + ntWidgetBuilder: (preferences, jsonData, enabled, + {onJsonLoadingWarning}) => + NTWidgetContainerModel.fromJson( + ntConnection: ntConnection, + jsonData: jsonData, + preferences: preferences, + onJsonLoadingWarning: onJsonLoadingWarning, + ), enabled: ntConnection.isNT4Connected, tabGrid: this, onDragCancel: _layoutContainerOnDragCancel, From 23f6d241664b4c646261ace6d0b0debbb5382280 Mon Sep 17 00:00:00 2001 From: Gold87 Date: Sun, 9 Jun 2024 18:08:45 -0400 Subject: [PATCH 4/4] Refactor tab data to include grid --- lib/pages/dashboard_page.dart | 170 ++++++++++++------------ lib/util/tab_data.dart | 11 ++ lib/widgets/editable_tab_bar.dart | 18 +-- test/widgets/editable_tab_bar_test.dart | 169 ++++++++++++----------- 4 files changed, 193 insertions(+), 175 deletions(-) create mode 100644 lib/util/tab_data.dart diff --git a/lib/pages/dashboard_page.dart b/lib/pages/dashboard_page.dart index 45db11e0..2d00fe1a 100644 --- a/lib/pages/dashboard_page.dart +++ b/lib/pages/dashboard_page.dart @@ -22,6 +22,7 @@ import 'package:elastic_dashboard/services/nt_connection.dart'; import 'package:elastic_dashboard/services/settings.dart'; import 'package:elastic_dashboard/services/shuffleboard_nt_listener.dart'; import 'package:elastic_dashboard/services/update_checker.dart'; +import 'package:elastic_dashboard/util/tab_data.dart'; import 'package:elastic_dashboard/widgets/custom_appbar.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/dialog_toggle_switch.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/layout_drag_tile.dart'; @@ -55,8 +56,6 @@ class _DashboardPageState extends State with WindowListener { late final SharedPreferences preferences = widget.preferences; late final UpdateChecker _updateChecker; - final List _grids = []; - final List _tabData = []; final Function _mapEquals = const DeepCollectionEquality().equals; @@ -111,7 +110,7 @@ class _DashboardPageState extends State with WindowListener { widget.ntConnection.addConnectedListener(() { setState(() { - for (TabGridModel grid in _grids) { + for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) { grid.onNTConnect(); } }); @@ -119,7 +118,7 @@ class _DashboardPageState extends State with WindowListener { widget.ntConnection.addDisconnectedListener(() { setState(() { - for (TabGridModel grid in _grids) { + for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) { grid.onNTDisconnect(); } }); @@ -164,14 +163,14 @@ class _DashboardPageState extends State with WindowListener { return; } - _tabData.add(TabData(name: tab)); - _grids.add( - TabGridModel( + _tabData.add(TabData( + name: tab, + tabGrid: TabGridModel( ntConnection: widget.ntConnection, preferences: widget.preferences, onAddWidgetPressed: _displayAddWidgetDialog, ), - ); + )); }, onWidgetAdded: (widgetData) { if (preferences.getBool(PrefKeys.layoutLocked) ?? @@ -189,12 +188,16 @@ class _DashboardPageState extends State with WindowListener { String tabName = widgetDataCopy['tab']; if (!tabNamesList.contains(tabName)) { - _tabData.add(TabData(name: tabName)); - _grids.add(TabGridModel( - ntConnection: widget.ntConnection, - preferences: widget.preferences, - onAddWidgetPressed: _displayAddWidgetDialog, - )); + _tabData.add( + TabData( + name: tabName, + tabGrid: TabGridModel( + ntConnection: widget.ntConnection, + preferences: widget.preferences, + onAddWidgetPressed: _displayAddWidgetDialog, + ), + ), + ); tabNamesList.add(tabName); } @@ -205,7 +208,7 @@ class _DashboardPageState extends State with WindowListener { return; } - _grids[tabIndex].addWidgetFromTabJson(widgetDataCopy); + _tabData[tabIndex].tabGrid.addWidgetFromTabJson(widgetDataCopy); setState(() {}); }, @@ -251,11 +254,10 @@ class _DashboardPageState extends State with WindowListener { for (int i = 0; i < _tabData.length; i++) { TabData data = _tabData[i]; - TabGridModel grid = _grids[i]; gridData.add({ 'name': data.name, - 'grid_layout': grid.toJson(), + 'grid_layout': data.tabGrid.toJson(), }); } @@ -555,7 +557,6 @@ class _DashboardPageState extends State with WindowListener { } _tabData.clear(); - _grids.clear(); for (Map data in jsonData['tabs']) { if (tryCast(data['name']) == null) { @@ -569,45 +570,47 @@ class _DashboardPageState extends State with WindowListener { continue; } - _tabData.add(TabData(name: data['name'])); - - _grids.add( - TabGridModel.fromJson( - ntConnection: widget.ntConnection, - preferences: widget.preferences, - jsonData: data['grid_layout'], - onAddWidgetPressed: _displayAddWidgetDialog, - onJsonLoadingWarning: _showJsonLoadingWarning, + _tabData.add( + TabData( + name: data['name'], + tabGrid: TabGridModel.fromJson( + ntConnection: widget.ntConnection, + preferences: widget.preferences, + jsonData: data['grid_layout'], + onAddWidgetPressed: _displayAddWidgetDialog, + onJsonLoadingWarning: _showJsonLoadingWarning, + ), ), ); } _createDefaultTabs(); - if (_currentTabIndex >= _grids.length) { - _currentTabIndex = _grids.length - 1; + if (_currentTabIndex >= _tabData.length) { + _currentTabIndex = _tabData.length - 1; } } void _createDefaultTabs() { - if (_tabData.isEmpty || _grids.isEmpty) { + if (_tabData.isEmpty) { logger.info('Creating default Teleoperated and Autonomous tabs'); setState(() { _tabData.addAll([ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ]); - - _grids.addAll([ - TabGridModel( - ntConnection: widget.ntConnection, - preferences: widget.preferences, - onAddWidgetPressed: _displayAddWidgetDialog, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: widget.ntConnection, + preferences: widget.preferences, + onAddWidgetPressed: _displayAddWidgetDialog, + ), ), - TabGridModel( - ntConnection: widget.ntConnection, - preferences: widget.preferences, - onAddWidgetPressed: _displayAddWidgetDialog, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: widget.ntConnection, + preferences: widget.preferences, + onAddWidgetPressed: _displayAddWidgetDialog, + ), ), ]); }); @@ -753,12 +756,14 @@ class _DashboardPageState extends State with WindowListener { String newTabName = 'Tab ${_tabData.length + 1}'; int newTabIndex = _tabData.length; - _tabData.add(TabData(name: newTabName)); - _grids.add( - TabGridModel( - ntConnection: widget.ntConnection, - preferences: widget.preferences, - onAddWidgetPressed: _displayAddWidgetDialog, + _tabData.add( + TabData( + name: newTabName, + tabGrid: TabGridModel( + ntConnection: widget.ntConnection, + preferences: widget.preferences, + onAddWidgetPressed: _displayAddWidgetDialog, + ), ), ); @@ -789,11 +794,10 @@ class _DashboardPageState extends State with WindowListener { _currentTabIndex--; } - _grids[oldTabIndex].onDestroy(); + _tabData[oldTabIndex].tabGrid.onDestroy(); setState(() { _tabData.removeAt(oldTabIndex); - _grids.removeAt(oldTabIndex); }); }); }, @@ -801,14 +805,14 @@ class _DashboardPageState extends State with WindowListener { } void _lockLayout() async { - for (TabGridModel grid in _grids) { + for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) { grid.lockLayout(); } await preferences.setBool(PrefKeys.layoutLocked, true); } void _unlockLayout() async { - for (TabGridModel grid in _grids) { + for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) { grid.unlockLayout(); } await preferences.setBool(PrefKeys.layoutLocked, false); @@ -1020,7 +1024,7 @@ class _DashboardPageState extends State with WindowListener { await preferences.setInt(PrefKeys.gridSize, newGridSize); - for (TabGridModel grid in _grids) { + for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) { grid.resizeGrid(_gridSize, _gridSize); } }, @@ -1039,7 +1043,7 @@ class _DashboardPageState extends State with WindowListener { await preferences.setDouble(PrefKeys.cornerRadius, newRadius); setState(() { - for (TabGridModel grid in _grids) { + for (TabGridModel grid in _tabData.map((e) => e.tabGrid)) { grid.refreshAllContainers(); } }); @@ -1223,16 +1227,11 @@ class _DashboardPageState extends State with WindowListener { logger.info('Moving current tab at index $_currentTabIndex to the left'); setState(() { - // Swap the tab data + // Swap the tabs TabData tempData = _tabData[_currentTabIndex - 1]; _tabData[_currentTabIndex - 1] = _tabData[_currentTabIndex]; _tabData[_currentTabIndex] = tempData; - // Swap the tab grids - TabGridModel tempGrid = _grids[_currentTabIndex - 1]; - _grids[_currentTabIndex - 1] = _grids[_currentTabIndex]; - _grids[_currentTabIndex] = tempGrid; - _currentTabIndex -= 1; }); } @@ -1250,16 +1249,11 @@ class _DashboardPageState extends State with WindowListener { logger.info('Moving current tab at index $_currentTabIndex to the right'); setState(() { - // Swap the tab data + // Swap the tabs TabData tempData = _tabData[_currentTabIndex + 1]; _tabData[_currentTabIndex + 1] = _tabData[_currentTabIndex]; _tabData[_currentTabIndex] = tempData; - // Swap the tab grids - TabGridModel tempGrid = _grids[_currentTabIndex + 1]; - _grids[_currentTabIndex + 1] = _grids[_currentTabIndex]; - _grids[_currentTabIndex] = tempGrid; - _currentTabIndex += 1; }); } @@ -1348,7 +1342,9 @@ class _DashboardPageState extends State with WindowListener { Defaults.layoutLocked) ? () { setState(() { - _grids[_currentTabIndex].clearWidgets(context); + _tabData[_currentTabIndex] + .tabGrid + .clearWidgets(context); }); } : null, @@ -1483,14 +1479,18 @@ class _DashboardPageState extends State with WindowListener { _tabData[index] = newData; }); }, - onTabCreate: (tab) { + onTabCreate: () { + String tabName = 'Tab ${_tabData.length + 1}'; setState(() { - _tabData.add(tab); - _grids.add(TabGridModel( - ntConnection: widget.ntConnection, - preferences: widget.preferences, - onAddWidgetPressed: _displayAddWidgetDialog, - )); + _tabData.add( + TabData( + name: tabName, + tabGrid: TabGridModel( + ntConnection: widget.ntConnection, + preferences: widget.preferences, + onAddWidgetPressed: _displayAddWidgetDialog, + )), + ); }); }, onTabDestroy: (index) { @@ -1505,11 +1505,10 @@ class _DashboardPageState extends State with WindowListener { _currentTabIndex--; } - _grids[index].onDestroy(); + _tabData[index].tabGrid.onDestroy(); setState(() { _tabData.removeAt(index); - _grids.removeAt(index); }); }); }, @@ -1517,26 +1516,31 @@ class _DashboardPageState extends State with WindowListener { setState(() => _currentTabIndex = index); }, tabData: _tabData, - tabViews: _grids, ), _AddWidgetDialog( ntConnection: widget.ntConnection, preferences: widget.preferences, - grid: () => _grids[_currentTabIndex], + grid: () => _tabData[_currentTabIndex].tabGrid, visible: _addWidgetDialogVisible, onNTDragUpdate: (globalPosition, widget) { - _grids[_currentTabIndex] + _tabData[_currentTabIndex] + .tabGrid .addDragInWidget(widget, globalPosition); }, onNTDragEnd: (widget) { - _grids[_currentTabIndex].placeDragInWidget(widget); + _tabData[_currentTabIndex] + .tabGrid + .placeDragInWidget(widget); }, onLayoutDragUpdate: (globalPosition, widget) { - _grids[_currentTabIndex] + _tabData[_currentTabIndex] + .tabGrid .addDragInWidget(widget, globalPosition); }, onLayoutDragEnd: (widget) { - _grids[_currentTabIndex].placeDragInWidget(widget); + _tabData[_currentTabIndex] + .tabGrid + .placeDragInWidget(widget); }, onClose: () { setState(() => _addWidgetDialogVisible = false); diff --git a/lib/util/tab_data.dart b/lib/util/tab_data.dart new file mode 100644 index 00000000..78dc7cfd --- /dev/null +++ b/lib/util/tab_data.dart @@ -0,0 +1,11 @@ +import 'package:elastic_dashboard/widgets/tab_grid.dart'; + +class TabData { + String name; + TabGridModel tabGrid; + + TabData({ + required this.name, + required this.tabGrid, + }); +} diff --git a/lib/widgets/editable_tab_bar.dart b/lib/widgets/editable_tab_bar.dart index 6f9d7b1d..5a736b53 100644 --- a/lib/widgets/editable_tab_bar.dart +++ b/lib/widgets/editable_tab_bar.dart @@ -7,22 +7,16 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:transitioned_indexed_stack/transitioned_indexed_stack.dart'; import 'package:elastic_dashboard/services/settings.dart'; +import 'package:elastic_dashboard/util/tab_data.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/dialog_text_input.dart'; import 'package:elastic_dashboard/widgets/tab_grid.dart'; -class TabData { - String name; - - TabData({required this.name}); -} - class EditableTabBar extends StatelessWidget { final SharedPreferences preferences; - final List tabViews; final List tabData; - final Function(TabData tab) onTabCreate; + final Function() onTabCreate; final Function(int index) onTabDestroy; final Function() onTabMoveLeft; final Function() onTabMoveRight; @@ -36,7 +30,6 @@ class EditableTabBar extends StatelessWidget { required this.preferences, required this.currentIndex, required this.tabData, - required this.tabViews, required this.onTabCreate, required this.onTabDestroy, required this.onTabMoveLeft, @@ -79,10 +72,7 @@ class EditableTabBar extends StatelessWidget { } void createTab() { - String tabName = 'Tab ${tabData.length + 1}'; - TabData data = TabData(name: tabName); - - onTabCreate.call(data); + onTabCreate(); } void closeTab(int index) { @@ -291,7 +281,7 @@ class EditableTabBar extends StatelessWidget { curve: Curves.decelerate, index: currentIndex, children: [ - for (TabGridModel grid in tabViews) + for (TabGridModel grid in tabData.map((e) => e.tabGrid)) ChangeNotifierProvider.value( value: grid, child: const TabGrid(), diff --git a/test/widgets/editable_tab_bar_test.dart b/test/widgets/editable_tab_bar_test.dart index ba8f672e..19eb6735 100644 --- a/test/widgets/editable_tab_bar_test.dart +++ b/test/widgets/editable_tab_bar_test.dart @@ -6,6 +6,7 @@ import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:elastic_dashboard/util/tab_data.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/dialog_text_input.dart'; import 'package:elastic_dashboard/widgets/editable_tab_bar.dart'; import 'package:elastic_dashboard/widgets/tab_grid.dart'; @@ -50,22 +51,24 @@ void main() { preferences: preferences, currentIndex: 0, tabData: [ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ], - tabViews: [ - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), ], - onTabCreate: (tab) {}, + onTabCreate: () {}, onTabDestroy: (index) {}, onTabMoveLeft: () {}, onTabMoveRight: () {}, @@ -99,22 +102,24 @@ void main() { preferences: preferences, currentIndex: 0, tabData: [ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ], - tabViews: [ - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), ], - onTabCreate: (tab) { + onTabCreate: () { tabBarFunctions.onTabCreate(); }, onTabDestroy: (index) { @@ -159,22 +164,24 @@ void main() { preferences: preferences, currentIndex: 0, tabData: [ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ], - tabViews: [ - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), ], - onTabCreate: (tab) { + onTabCreate: () { tabBarFunctions.onTabCreate(); }, onTabDestroy: (index) { @@ -219,22 +226,24 @@ void main() { preferences: preferences, currentIndex: 0, tabData: [ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ], - tabViews: [ - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), ], - onTabCreate: (tab) { + onTabCreate: () { tabBarFunctions.onTabCreate(); }, onTabDestroy: (index) { @@ -292,22 +301,24 @@ void main() { preferences: preferences, currentIndex: 0, tabData: [ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ], - tabViews: [ - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), ], - onTabCreate: (tab) { + onTabCreate: () { tabBarFunctions.onTabCreate(); }, onTabDestroy: (index) { @@ -376,22 +387,24 @@ void main() { preferences: preferences, currentIndex: 0, tabData: [ - TabData(name: 'Teleoperated'), - TabData(name: 'Autonomous'), - ], - tabViews: [ - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Teleoperated', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), - TabGridModel( - ntConnection: mockNTConnection, - preferences: preferences, - onAddWidgetPressed: () {}, + TabData( + name: 'Autonomous', + tabGrid: TabGridModel( + ntConnection: mockNTConnection, + preferences: preferences, + onAddWidgetPressed: () {}, + ), ), ], - onTabCreate: (tab) { + onTabCreate: () { tabBarFunctions.onTabCreate(); }, onTabDestroy: (index) {