Files
gomix_flutter/lib/port_connection_card.dart

137 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:gomix_flutter/mixer_state.dart' as mixer;
class PortConnectionCard extends StatefulWidget {
final mixer.Port sourcePort;
final mixer.State connection;
final mixer.MixerState mixerState;
final Function(Map<String, Object> data) sendAction;
final bool isOutput;
const PortConnectionCard(
{super.key,
required this.sourcePort,
required this.connection,
required this.mixerState,
required this.sendAction,
required this.isOutput});
@override
State<PortConnectionCard> createState() => _PortConnectionCardState();
}
class _PortConnectionCardState extends State<PortConnectionCard> {
double _sliderValue = 0;
int _debounceTimer = 0;
bool _sliderActive = false;
String toUUID = "";
String portName = "";
void updatePortData() {
toUUID = widget.connection.toUuid ?? "";
mixer.Port toPort = widget.mixerState.outputs.firstWhere(
(el) => el.uuid == toUUID,
orElse: () => mixer.Port(
name: "Invalid Port",
properties: mixer.Properties(backend: "N/A", channels: 0),
state: mixer.State(balance: 1, mute: true, volume: 0),
uuid: toUUID,
route: []));
portName = widget.isOutput ? widget.sourcePort.name : toPort.name;
}
@override
void initState() {
_sliderValue = widget.connection.volume;
updatePortData();
super.initState();
}
@override
void didUpdateWidget(PortConnectionCard oldWidget) {
if (_sliderActive) return;
_sliderValue = widget.connection.volume;
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(portName),
Row(
children: [
Expanded(
child: Slider(
min: 0,
max: 4,
value: _sliderValue,
label: _sliderValue.toStringAsFixed(2),
allowedInteraction: SliderInteraction.slideThumb,
onChangeStart: ((val) {
_sliderActive = true;
}),
onChangeEnd: ((val) {
// Send the current state to make sure we
// don't miss the last value due to the debounce
widget.sendAction({
"method": "setRouteState",
"UUID": widget.sourcePort.uuid,
"toUUID": widget.connection.toUuid ?? "",
"routeStateData": {"volume": val}
});
// Make sure the slider value is still correct
// after suppressing updates
_sliderActive = false;
setState(() {
_sliderValue = widget.connection.volume;
});
}),
onChanged: (val) {
setState(() {
_sliderValue = val;
});
if (DateTime.now().millisecondsSinceEpoch -
_debounceTimer <
30) {
return;
}
_debounceTimer = DateTime.now().millisecondsSinceEpoch;
widget.sendAction({
"method": "setRouteState",
"UUID": widget.sourcePort.uuid,
"toUUID": widget.connection.toUuid ?? "",
"routeStateData": {"volume": val}
});
})),
IconButton.filledTonal(
onPressed: () {
widget.sendAction({
"method": "setRouteState",
"UUID": widget.sourcePort.uuid,
"toUUID": widget.connection.toUuid ?? "",
"routeStateData": {"mute": !widget.connection.mute}
});
},
iconSize: 20,
icon: widget.connection.mute
? const Icon(Icons.volume_off_outlined)
: const Icon(Icons.volume_up_outlined)),
const SizedBox(width: 5),
IconButton.filled(
onPressed: () {
widget.sendAction({
"method": "deleteRoute",
"UUID": widget.sourcePort.uuid,
"toUUID": widget.connection.toUuid ?? ""
});
},
iconSize: 20,
icon: const Icon(Icons.delete)),
],
)
],
);
}
}