Skip to content

Commit

Permalink
Allow non-widget tables to create list layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
Gold872 committed Dec 21, 2023
1 parent 08d941c commit 3daf86c
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 96 deletions.
23 changes: 14 additions & 9 deletions lib/pages/dashboard_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:io';

import 'package:elastic_dashboard/widgets/draggable_containers/models/widget_container_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -30,7 +31,6 @@ import 'package:elastic_dashboard/widgets/network_tree/networktables_tree.dart';
import 'package:elastic_dashboard/widgets/settings_dialog.dart';
import 'package:elastic_dashboard/widgets/tab_grid.dart';
import '../widgets/draggable_containers/models/layout_container_model.dart';
import '../widgets/draggable_containers/models/nt_widget_container_model.dart';

class DashboardPage extends StatefulWidget {
final SharedPreferences preferences;
Expand Down Expand Up @@ -1276,17 +1276,17 @@ class _DashboardPageState extends State<DashboardPage> with WindowListener {
visible: addWidgetDialogVisible,
onNTDragUpdate: (globalPosition, widget) {
grids[currentTabIndex]
.addNTDragInWidget(widget, globalPosition);
.addDragInWidget(widget, globalPosition);
},
onNTDragEnd: (widget) {
grids[currentTabIndex].placeNTDragInWidget(widget);
grids[currentTabIndex].placeDragInWidget(widget);
},
onLayoutDragUpdate: (globalPosition, widget) {
grids[currentTabIndex]
.addLayoutDragInWidget(widget, globalPosition);
.addDragInWidget(widget, globalPosition);
},
onLayoutDragEnd: (widget) {
grids[currentTabIndex].placeLayoutDragInWidget(widget);
grids[currentTabIndex].placeDragInWidget(widget);
},
onClose: () {
setState(() => addWidgetDialogVisible = false);
Expand Down Expand Up @@ -1355,9 +1355,9 @@ class AddWidgetDialog extends StatelessWidget {
final TabGrid Function() grid;
final bool visible;

final Function(Offset globalPosition, NTWidgetContainerModel widget)?
final Function(Offset globalPosition, WidgetContainerModel widget)?
onNTDragUpdate;
final Function(NTWidgetContainerModel widget)? onNTDragEnd;
final Function(WidgetContainerModel widget)? onNTDragEnd;

final Function(Offset globalPosition, LayoutContainerModel widget)?
onLayoutDragUpdate;
Expand Down Expand Up @@ -1411,10 +1411,15 @@ class AddWidgetDialog extends StatelessWidget {
child: TabBarView(
children: [
NetworkTableTree(
listLayoutBuilder: (
{required title, required children}) {
return grid().createListLayout(
title: title,
children: children,
);
},
onDragUpdate: onNTDragUpdate,
onDragEnd: onNTDragEnd,
widgetContainerBuilder: (widgetContainer) =>
grid().createNTWidgetContainer(widgetContainer),
),
ListView(
children: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ListLayoutModel extends LayoutContainerModel {
required super.title,
required this.tabGrid,
required this.onDragCancel,
this.children = const [],
super.minWidth,
super.minHeight,
this.labelPosition = 'TOP',
Expand Down
54 changes: 30 additions & 24 deletions lib/widgets/network_tree/networktables_tree.dart
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
import 'dart:ui';

import 'package:elastic_dashboard/widgets/draggable_containers/models/list_layout_model.dart';
import 'package:elastic_dashboard/widgets/draggable_containers/models/nt_widget_container_model.dart';
import 'package:elastic_dashboard/widgets/draggable_containers/models/widget_container_model.dart';
import 'package:flutter/material.dart';

import 'package:collection/collection.dart';
import 'package:flutter_fancy_tree_view/flutter_fancy_tree_view.dart';

import 'package:elastic_dashboard/services/nt4_client.dart';
import 'package:elastic_dashboard/services/nt_connection.dart';
import 'package:elastic_dashboard/widgets/draggable_containers/draggable_widget_container.dart';
import 'package:elastic_dashboard/widgets/network_tree/networktables_tree_row.dart';
import '../draggable_containers/models/nt_widget_container_model.dart';

typedef ListLayoutBuilder = ListLayoutModel Function({
required String title,
required List<NTWidgetContainerModel> children,
});

class NetworkTableTree extends StatefulWidget {
final Function(Offset globalPosition, NTWidgetContainerModel widget)?
final ListLayoutBuilder listLayoutBuilder;

final Function(Offset globalPosition, WidgetContainerModel widget)?
onDragUpdate;
final Function(NTWidgetContainerModel widget)? onDragEnd;
final NTWidgetContainerModel? Function(WidgetContainer? widget)?
widgetContainerBuilder;
final Function(WidgetContainerModel widget)? onDragEnd;

const NetworkTableTree(
{super.key,
this.onDragUpdate,
this.onDragEnd,
this.widgetContainerBuilder});
const NetworkTableTree({
super.key,
required this.listLayoutBuilder,
this.onDragUpdate,
this.onDragEnd,
});

@override
State<NetworkTableTree> createState() => _NetworkTableTreeState();
Expand All @@ -32,12 +39,10 @@ class _NetworkTableTreeState extends State<NetworkTableTree> {
final NetworkTableTreeRow root = NetworkTableTreeRow(topic: '/', rowName: '');
late final TreeController<NetworkTableTreeRow> treeController;

late final Function(Offset globalPosition, NTWidgetContainerModel widget)?
late final Function(Offset globalPosition, WidgetContainerModel widget)?
onDragUpdate = widget.onDragUpdate;
late final Function(NTWidgetContainerModel widget)? onDragEnd =
late final Function(WidgetContainerModel widget)? onDragEnd =
widget.onDragEnd;
late final NTWidgetContainerModel? Function(WidgetContainer? widget)?
widgetContainerBuilder = widget.widgetContainerBuilder;

late final Function(NT4Topic topic) onNewTopicAnnounced;

Expand Down Expand Up @@ -122,9 +127,9 @@ class _NetworkTableTreeState extends State<NetworkTableTree> {
return TreeTile(
key: UniqueKey(),
entry: entry,
listLayoutBuilder: widget.listLayoutBuilder,
onDragUpdate: onDragUpdate,
onDragEnd: onDragEnd,
widgetContainerBuilder: widgetContainerBuilder,
onTap: () {
setState(() => treeController.toggleExpansion(entry.node));
},
Expand All @@ -139,20 +144,21 @@ class TreeTile extends StatelessWidget {
super.key,
required this.entry,
required this.onTap,
required this.listLayoutBuilder,
this.onDragUpdate,
this.onDragEnd,
this.widgetContainerBuilder,
});

final TreeEntry<NetworkTableTreeRow> entry;
final VoidCallback onTap;
final Function(Offset globalPosition, NTWidgetContainerModel widget)?

final ListLayoutBuilder listLayoutBuilder;

final Function(Offset globalPosition, WidgetContainerModel widget)?
onDragUpdate;
final Function(NTWidgetContainerModel widget)? onDragEnd;
final NTWidgetContainerModel? Function(WidgetContainer? widget)?
widgetContainerBuilder;
final Function(WidgetContainerModel widget)? onDragEnd;

NTWidgetContainerModel? draggingWidget;
WidgetContainerModel? draggingWidget;

@override
Widget build(BuildContext context) {
Expand All @@ -172,8 +178,8 @@ class TreeTile extends StatelessWidget {
return;
}

draggingWidget = widgetContainerBuilder
?.call(await entry.node.toWidgetContainer());
draggingWidget = await entry.node
.toWidgetContainerModel(listLayoutBuilder: listLayoutBuilder);
},
onPanUpdate: (details) {
if (draggingWidget == null) {
Expand Down
55 changes: 55 additions & 0 deletions lib/widgets/network_tree/networktables_tree_row.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'package:elastic_dashboard/widgets/draggable_containers/models/nt_widget_container_model.dart';
import 'package:elastic_dashboard/widgets/draggable_containers/models/widget_container_model.dart';
import 'package:elastic_dashboard/widgets/network_tree/networktables_tree.dart';
import 'package:flutter/material.dart';

import 'package:elastic_dashboard/services/nt4_client.dart';
Expand Down Expand Up @@ -154,6 +157,58 @@ class NetworkTableTreeRow {
return NTWidgetBuilder.buildNTWidgetFromType(type, topic);
}

Future<List<NTWidgetContainerModel>?> getListLayoutChildren() async {
List<NTWidgetContainerModel> listChildren = [];
for (NetworkTableTreeRow child in children) {
if (child.rowName.startsWith('.')) {
continue;
}
WidgetContainerModel? childModel =
await child.toWidgetContainerModel(resortToListLayout: false);

if (childModel is NTWidgetContainerModel) {
listChildren.add(childModel);
}
}

if (listChildren.isEmpty) {
return null;
}

return listChildren;
}

Future<WidgetContainerModel?> toWidgetContainerModel({
bool resortToListLayout = true,
ListLayoutBuilder? listLayoutBuilder,
}) async {
NTWidget? primary = await getPrimaryWidget();

if (primary == null) {
if (resortToListLayout) {
List<NTWidgetContainerModel>? listLayoutChildren =
await getListLayoutChildren();

if (listLayoutChildren != null) {
return listLayoutBuilder?.call(
title: rowName,
children: listLayoutChildren,
);
}
}
return null;
}

double width = NTWidgetBuilder.getDefaultWidth(primary);
double height = NTWidgetBuilder.getDefaultHeight(primary);

return NTWidgetContainerModel(
initialPosition: Rect.fromLTWH(0.0, 0.0, width, height),
title: rowName,
child: primary,
);
}

Future<WidgetContainer?> toWidgetContainer() async {
NTWidget? primary = await getPrimaryWidget();

Expand Down
81 changes: 18 additions & 63 deletions lib/widgets/tab_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ class TabGrid extends StatelessWidget {

void layoutDragOutEnd(WidgetContainerModel widget) {
if (widget is NTWidgetContainerModel) {
placeNTDragInWidget(widget, true);
placeDragInWidget(widget, true);
}
}

Expand Down Expand Up @@ -432,58 +432,7 @@ class TabGrid extends StatelessWidget {
refresh();
}

void addLayoutDragInWidget(
LayoutContainerModel layout, Offset globalPosition) {
Offset localPosition = getLocalPosition(globalPosition);
layout.setDraggingRect(
Rect.fromLTWH(
localPosition.dx,
localPosition.dy,
layout.draggingRect.width,
layout.draggingRect.height,
),
);
_containerDraggingIn = MapEntry(layout, globalPosition);
refresh();
}

void placeLayoutDragInWidget(LayoutContainerModel layout) {
if (_containerDraggingIn == null) {
return;
}

Offset globalPosition = _containerDraggingIn!.value;

Offset localPosition = getLocalPosition(globalPosition);

double previewX = DraggableWidgetContainer.snapToGrid(localPosition.dx);
double previewY = DraggableWidgetContainer.snapToGrid(localPosition.dy);

Rect previewLocation = Rect.fromLTWH(previewX, previewY,
layout.displayRect.width, layout.displayRect.height);

if (!isValidLocation(previewLocation)) {
_containerDraggingIn = null;

refresh();
return;
}

double width = layout.displayRect.width;
double height = layout.displayRect.height;

layout.setDisplayRect(Rect.fromLTWH(previewX, previewY, width, height));
layout.setDraggingRect(Rect.fromLTWH(previewX, previewY, width, height));
layout
.setDragStartLocation(Rect.fromLTWH(previewX, previewY, width, height));

addWidget(layout);
_containerDraggingIn = null;

refresh();
}

void addNTDragInWidget(NTWidgetContainerModel widget, Offset globalPosition) {
void addDragInWidget(WidgetContainerModel widget, Offset globalPosition) {
Offset localPosition = getLocalPosition(globalPosition);
widget.setDraggingRect(
Rect.fromLTWH(
Expand All @@ -497,7 +446,7 @@ class TabGrid extends StatelessWidget {
refresh();
}

void placeNTDragInWidget(NTWidgetContainerModel widget,
void placeDragInWidget(WidgetContainerModel widget,
[bool fromLayout = false]) {
if (_containerDraggingIn == null) {
return;
Expand All @@ -516,11 +465,12 @@ class TabGrid extends StatelessWidget {
Rect previewLocation = Rect.fromLTWH(previewX, previewY, width, height);
widget.setPreviewRect(previewLocation);

widget.updateMinimumSize();
widget.tryCast<NTWidgetContainerModel>()?.updateMinimumSize();
widget.setEnabled(ntConnection.isNT4Connected);

// If dragging into layout
if (isValidLayoutLocation(widget.cursorGlobalLocation)) {
if (widget is NTWidgetContainerModel &&
isValidLayoutLocation(widget.cursorGlobalLocation)) {
LayoutContainerModel layoutContainer =
getLayoutAtLocation(widget.cursorGlobalLocation)!;

Expand All @@ -530,10 +480,12 @@ class TabGrid extends StatelessWidget {
} else if (!isValidLocation(previewLocation)) {
_containerDraggingIn = null;

widget.child.dispose(deleting: !fromLayout);
if (!fromLayout) {
widget.child.unSubscribe();
widget.forceDispose();
if (widget is NTWidgetContainerModel) {
widget.child.dispose(deleting: !fromLayout);
if (!fromLayout) {
widget.child.unSubscribe();
widget.forceDispose();
}
}

refresh();
Expand All @@ -547,7 +499,7 @@ class TabGrid extends StatelessWidget {

_containerDraggingIn = null;

widget.child.dispose();
widget.tryCast<NTWidgetContainerModel>()?.child.dispose();

refresh();
}
Expand All @@ -574,15 +526,18 @@ class TabGrid extends StatelessWidget {
);
}

ListLayoutModel createListLayout() {
ListLayoutModel createListLayout(
{String title = 'List Layout',
List<NTWidgetContainerModel> children = const []}) {
return ListLayoutModel(
title: 'List Layout',
title: title,
initialPosition: Rect.fromLTWH(
0.0,
0.0,
Settings.gridSize.toDouble() * 2,
Settings.gridSize.toDouble() * 2,
),
children: children,
minWidth: 128.0 * 2,
minHeight: 128.0 * 2,
tabGrid: this,
Expand Down

0 comments on commit 3daf86c

Please sign in to comment.