import 'dart:math'; import 'package:flutter/material.dart'; import 'package:gomix_flutter/mixer_state.dart' as mixer; import 'package:gomix_flutter/mixing_card.dart'; import 'package:gomix_flutter/port_connection_card.dart'; import 'package:gomix_flutter/ports_tab.dart'; class PortConnectionDialog extends StatefulWidget { final Function(Map data) sendAction; final mixer.Port port; final bool isOutput; final DialogDataModel dataModel; final mixer.MixerState mixerState; const PortConnectionDialog( {super.key, required this.sendAction, required this.port, required this.dataModel, this.isOutput = false, required this.mixerState}); void show(BuildContext context) { showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: isOutput ? Text("Inputs > ${port.name}") : Text("${port.name} > Outputs"), content: this, ), ); } void showNewConnectionDialog(BuildContext context) { showDialog( context: context, builder: (BuildContext context) => AlertDialog( title: const Text("New connection"), content: PortsTab( mixerState: mixerState, sendAction: sendAction, // Can only select outputs if source port is an input and nice versa filter: (_, isOutput) => this.isOutput != isOutput, selectionCallback: (destination) { Navigator.pop(context); sendAction({ "method": "createRoute", "UUID": isOutput ? destination.uuid : port.uuid, "routeData": {"to": isOutput ? port.uuid : destination.uuid} }); }, ), ), ); } @override State createState() => _PortConnectionState(); } class _PortConnectionState extends State { List<(mixer.Port, mixer.State)> connections = []; List<(mixer.Port, mixer.State)> getConnections() { List<(mixer.Port, mixer.State)> connections = []; if (widget.isOutput) { for (mixer.Port input in widget.dataModel.mixerState.inputs) { for (mixer.State connection in input.route) { String toUUID = connection.toUuid ?? ""; if (toUUID == widget.port.uuid) connections.add((input, connection)); } } } else { connections = widget.dataModel.port.route .map((route) => (widget.port, route)) .toList(); } return connections; } var dataModelListener = () {}; @override void initState() { super.initState(); connections = getConnections(); dataModelListener = () { WidgetsBinding.instance.addPostFrameCallback((_) { setState(() { connections = getConnections(); }); }); }; widget.dataModel.addListener(dataModelListener); } @override void dispose() { widget.dataModel.removeListener(dataModelListener); super.dispose(); } @override Widget build(BuildContext context) { return SizedBox( width: min(MediaQuery.of(context).size.width, 400), child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: (connections .map((elem) => PortConnectionCard( sourcePort: elem.$1, connection: elem.$2, isOutput: widget.isOutput, mixerState: widget.mixerState, sendAction: widget.sendAction) as Widget) .toList()) + [ const SizedBox(height: 10), TextButton.icon( onPressed: () { widget.showNewConnectionDialog(context); }, icon: const Icon(Icons.add), label: const Text("New connection")) ], ), ), ); } }