Skip to content

Commit dc0b6a1

Browse files
committed
Updates to export button layout and use
1 parent 4d23535 commit dc0b6a1

File tree

2 files changed

+174
-138
lines changed

2 files changed

+174
-138
lines changed

ui/lib/export.dart

Lines changed: 119 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -4,70 +4,75 @@ import 'package:file_picker/file_picker.dart';
44
import 'package:flutter/material.dart';
55
import 'package:xml/xml.dart' as xml;
66

7-
class XmlExport extends StatelessWidget {
7+
class XmlExport {
88
const XmlExport(
9-
{super.key,
10-
required this.graphs,
11-
required this.graphIndex,
12-
required this.refCount});
9+
{required this.graphs, required this.graphIndex, required this.refCount});
1310

1411
final List<Graph> graphs;
1512
final int graphIndex;
1613
final int refCount;
1714

18-
@override
19-
Widget build(BuildContext context) {
20-
return IconButton(
21-
icon: Icon(Icons.code_off),
22-
tooltip: 'Export XML',
23-
onPressed: () {
24-
if (graphs.isNotEmpty) {
25-
final graph = graphs[graphIndex];
26-
// Export the selected graph
27-
final xml = _exportXML(graph, refCount);
28-
showDialog(
29-
context: context,
30-
builder: (context) => AlertDialog(
31-
title: Text("Export XML"),
32-
content: SingleChildScrollView(child: Text(xml)),
33-
actions: [
34-
TextButton(
35-
onPressed: () async {
36-
// Use FilePicker to save the XML file
37-
final result = await FilePicker.platform.saveFile(
38-
dialogTitle: 'Save XML File',
39-
fileName: 'graph.xml',
15+
void export(BuildContext context) {
16+
if (graphs.isNotEmpty) {
17+
final graph = graphs[graphIndex];
18+
// Export the selected graph
19+
final xml = _exportXML(graph, refCount);
20+
showDialog(
21+
context: context,
22+
builder: (context) => AlertDialog(
23+
title: Text("Export XML"),
24+
content: SingleChildScrollView(child: Text(xml)),
25+
actions: [
26+
TextButton(
27+
onPressed: () async {
28+
// Use FilePicker to save the XML file
29+
final result = await FilePicker.platform.saveFile(
30+
dialogTitle: 'Save XML File',
31+
fileName: 'graph.xml',
32+
);
33+
34+
if (result != null) {
35+
final file = File(result);
36+
await file.writeAsString(xml);
37+
38+
// Show a confirmation message
39+
if (context.mounted) {
40+
ScaffoldMessenger.of(context).showSnackBar(
41+
SnackBar(content: Text('XML file saved to $result')),
4042
);
41-
42-
if (result != null) {
43-
final file = File(result);
44-
await file.writeAsString(xml);
45-
46-
// Show a confirmation message
47-
if (context.mounted) {
48-
ScaffoldMessenger.of(context).showSnackBar(
49-
SnackBar(content: Text('XML file saved to $result')),
50-
);
51-
}
52-
}
53-
54-
// Close the dialog
55-
if (context.mounted) {
56-
Navigator.of(context).pop();
57-
}
58-
},
59-
child: Text("Save"),
60-
),
61-
TextButton(
62-
onPressed: () => Navigator.of(context).pop(),
63-
child: Text("Close"),
64-
),
65-
],
43+
}
44+
}
45+
46+
// Close the dialog
47+
if (context.mounted) {
48+
Navigator.of(context).pop();
49+
}
50+
},
51+
child: Text("Save"),
6652
),
67-
);
68-
}
69-
},
70-
);
53+
TextButton(
54+
onPressed: () => Navigator.of(context).pop(),
55+
child: Text("Close"),
56+
),
57+
],
58+
),
59+
);
60+
} else {
61+
// Show a message if there are no graphs to export
62+
showDialog(
63+
context: context,
64+
builder: (context) => AlertDialog(
65+
title: Text("No Graphs Defined!"),
66+
content: Text("There are no graphs to export."),
67+
actions: [
68+
TextButton(
69+
onPressed: () => Navigator.of(context).pop(),
70+
child: Text("Close"),
71+
),
72+
],
73+
),
74+
);
75+
}
7176
}
7277

7378
void _addReferenceElement(xml.XmlBuilder builder, Reference reference) {
@@ -237,68 +242,74 @@ class XmlExport extends StatelessWidget {
237242
} // End of _getTargets
238243
} // End of XmlExport
239244

240-
class DotExport extends StatelessWidget {
245+
class DotExport {
241246
const DotExport({
242-
super.key,
243247
required this.graphs,
244248
required this.graphIndex,
245249
});
246250

247251
final List<Graph> graphs;
248252
final int graphIndex;
249253

250-
@override
251-
Widget build(BuildContext context) {
252-
return IconButton(
253-
icon: Icon(Icons.code),
254-
tooltip: 'Export DOT',
255-
onPressed: () {
256-
// Check if there are any graphs available
257-
if (graphs.isNotEmpty) {
258-
final graph = graphs[graphIndex];
259-
// Export the selected graph
260-
final dot = _exportDOT(graph);
261-
showDialog(
262-
context: context,
263-
builder: (context) => AlertDialog(
264-
title: Text("Export DOT"),
265-
content: SingleChildScrollView(child: Text(dot)),
266-
actions: [
267-
TextButton(
268-
onPressed: () async {
269-
final result = await FilePicker.platform.saveFile(
270-
dialogTitle: 'Save DOT File',
271-
fileName: 'graph.dot',
254+
void export(BuildContext context) {
255+
if (graphs.isNotEmpty) {
256+
final graph = graphs[graphIndex];
257+
// Export the selected graph
258+
final dot = _exportDOT(graph);
259+
showDialog(
260+
context: context,
261+
builder: (context) => AlertDialog(
262+
title: Text("Export DOT"),
263+
content: SingleChildScrollView(child: Text(dot)),
264+
actions: [
265+
TextButton(
266+
onPressed: () async {
267+
final result = await FilePicker.platform.saveFile(
268+
dialogTitle: 'Save DOT File',
269+
fileName: 'graph.dot',
270+
);
271+
272+
if (result != null) {
273+
final file = File(result);
274+
await file.writeAsString(dot);
275+
276+
// Show a confirmation message
277+
if (context.mounted) {
278+
ScaffoldMessenger.of(context).showSnackBar(
279+
SnackBar(content: Text('DOT file saved to $result')),
272280
);
273-
274-
if (result != null) {
275-
final file = File(result);
276-
await file.writeAsString(dot);
277-
278-
// Show a confirmation message
279-
if (context.mounted) {
280-
ScaffoldMessenger.of(context).showSnackBar(
281-
SnackBar(content: Text('DOT file saved to $result')),
282-
);
283-
}
284-
}
285-
286-
if (context.mounted) {
287-
Navigator.of(context).pop(); // Close the dialog
288-
}
289-
},
290-
child: Text("Save"),
291-
),
292-
TextButton(
293-
onPressed: () => Navigator.of(context).pop(),
294-
child: Text("Close"),
295-
),
296-
],
281+
}
282+
}
283+
284+
if (context.mounted) {
285+
Navigator.of(context).pop(); // Close the dialog
286+
}
287+
},
288+
child: Text("Save"),
297289
),
298-
);
299-
}
300-
},
301-
);
290+
TextButton(
291+
onPressed: () => Navigator.of(context).pop(),
292+
child: Text("Close"),
293+
),
294+
],
295+
),
296+
);
297+
} else {
298+
// Show a message if there are no graphs to export
299+
showDialog(
300+
context: context,
301+
builder: (context) => AlertDialog(
302+
title: Text("No Graphs Defined!"),
303+
content: Text("There are no graphs to export."),
304+
actions: [
305+
TextButton(
306+
onPressed: () => Navigator.of(context).pop(),
307+
child: Text("Close"),
308+
),
309+
],
310+
),
311+
);
312+
}
302313
}
303314

304315
String _formatReferenceLabel(Reference reference) {

ui/lib/graph_editor.dart

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class GraphEditorState extends State<GraphEditor> {
172172
selectedNode = null;
173173
selectedEdge = null;
174174
selectedGraphRow = null;
175+
edgeStartNode = null;
176+
edgeStartOutput = null;
175177
});
176178
} // End of _deselectAll
177179

@@ -218,14 +220,40 @@ class GraphEditorState extends State<GraphEditor> {
218220

219221
return Scaffold(
220222
appBar: AppBar(
223+
centerTitle: true,
224+
title: Text(
225+
'Edge Studio',
226+
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
227+
),
221228
actions: [
222-
// IconButton to export the currently selected graph in DOT format.
223-
DotExport(graphs: graphs, graphIndex: selectedGraphIndex),
224-
// IconButton to export the currently selected graph in XML format.
225-
XmlExport(
226-
graphs: graphs,
227-
graphIndex: selectedGraphIndex,
228-
refCount: _refCount),
229+
PopupMenuButton<String>(
230+
icon: Icon(Icons.code_rounded), // Single export icon
231+
tooltip: 'Export',
232+
onSelected: (value) {
233+
if (value == 'Export DOT') {
234+
// Export the currently selected graph in DOT format.
235+
DotExport(graphs: graphs, graphIndex: selectedGraphIndex)
236+
.export(context);
237+
} else if (value == 'Export XML') {
238+
// Export the currently selected graph in XML format.
239+
XmlExport(
240+
graphs: graphs,
241+
graphIndex: selectedGraphIndex,
242+
refCount: _refCount,
243+
).export(context);
244+
}
245+
},
246+
itemBuilder: (context) => [
247+
PopupMenuItem(
248+
value: 'Export DOT',
249+
child: Text('Export DOT'),
250+
),
251+
PopupMenuItem(
252+
value: 'Export XML',
253+
child: Text('Export XML'),
254+
),
255+
],
256+
),
229257
],
230258
),
231259
body: Column(
@@ -1043,30 +1071,27 @@ class NodeAttributesPanel extends StatelessWidget {
10431071
},
10441072
),
10451073
SizedBox(height: 8.0),
1046-
SizedBox(
1047-
width: double.infinity,
1048-
child: DropdownButtonFormField<String>(
1049-
isExpanded: true,
1050-
value: selectedNode!.target,
1051-
decoration: InputDecoration(
1052-
labelText:
1053-
Text('Target', overflow: TextOverflow.ellipsis).data,
1054-
isDense: true,
1055-
),
1056-
items: supportedTargets
1057-
.map((target) => DropdownMenuItem<String>(
1058-
alignment: Alignment.centerLeft,
1059-
value: target.name,
1060-
child: Text(
1061-
target.name,
1062-
overflow: TextOverflow.ellipsis,
1063-
),
1064-
))
1065-
.toList(),
1066-
onChanged: (newValue) {
1067-
onTargetChanged(newValue!);
1068-
},
1074+
DropdownButtonFormField<String>(
1075+
isExpanded: true,
1076+
value: selectedNode!.target,
1077+
decoration: InputDecoration(
1078+
labelText:
1079+
Text('Target', overflow: TextOverflow.ellipsis).data,
1080+
isDense: true,
10691081
),
1082+
items: supportedTargets
1083+
.map((target) => DropdownMenuItem<String>(
1084+
alignment: Alignment.centerLeft,
1085+
value: target.name,
1086+
child: Text(
1087+
target.name,
1088+
overflow: TextOverflow.ellipsis,
1089+
),
1090+
))
1091+
.toList(),
1092+
onChanged: (newValue) {
1093+
onTargetChanged(newValue!);
1094+
},
10701095
),
10711096
SizedBox(height: 8.0),
10721097
DropdownButtonFormField<String>(

0 commit comments

Comments
 (0)