diff --git a/lib/bluetooth/devices/bluetooth_device.dart b/lib/bluetooth/devices/bluetooth_device.dart index 9ed9f72..e4aaf83 100644 --- a/lib/bluetooth/devices/bluetooth_device.dart +++ b/lib/bluetooth/devices/bluetooth_device.dart @@ -116,6 +116,7 @@ abstract class BluetoothDevice extends BaseDevice { //DeviceType.rideRight => ZwiftRide(scanResult), // see comment above ZwiftDeviceType.clickV2Left => ZwiftClickV2(scanResult), //DeviceType.clickV2Right => ZwiftClickV2(scanResult), // see comment above + _ when scanResult.name == 'Zwift Ride' => ZwiftRide(scanResult), // e.g. old firmware _ => null, }; } else { diff --git a/lib/bluetooth/devices/openbikecontrol/obc_mdns_emulator.dart b/lib/bluetooth/devices/openbikecontrol/obc_mdns_emulator.dart index 2ea3ea2..e8609e8 100644 --- a/lib/bluetooth/devices/openbikecontrol/obc_mdns_emulator.dart +++ b/lib/bluetooth/devices/openbikecontrol/obc_mdns_emulator.dart @@ -39,8 +39,7 @@ class OpenBikeControlMdnsEmulator { } if (localIP == null) { - print('Could not find network interface'); - return; + throw 'Could not find network interface'; } _createTcpServer(); diff --git a/lib/pages/touch_area.dart b/lib/pages/touch_area.dart index 828dedc..059da1f 100644 --- a/lib/pages/touch_area.dart +++ b/lib/pages/touch_area.dart @@ -14,6 +14,7 @@ import 'package:swift_control/utils/i18n_extension.dart'; import 'package:swift_control/widgets/keymap_explanation.dart'; import 'package:swift_control/widgets/testbed.dart'; import 'package:swift_control/widgets/ui/button_widget.dart'; +import 'package:swift_control/widgets/ui/colors.dart'; import 'package:window_manager/window_manager.dart'; import '../utils/actions/base_actions.dart'; @@ -397,7 +398,7 @@ class KeypairExplanation extends StatelessWidget { ) else Icon(keyPair.icon), - if (keyPair.inGameAction != null && core.logic.emulatorEnabled && keyPair.touchPosition == Offset.zero) + if (keyPair.inGameAction != null && core.logic.emulatorEnabled) _KeyWidget( label: [ keyPair.inGameAction.toString().split('.').last, @@ -420,12 +421,12 @@ class KeypairExplanation extends StatelessWidget { _KeyWidget( label: keyPair.toString(), ), - if (keyPair.isLongPress) Text(context.i18n.longPress, style: TextStyle(fontSize: 10)), ] else ...[ if (!withKey && keyPair.touchPosition != Offset.zero && core.logic.showLocalRemoteOptions) _KeyWidget(label: 'X:${keyPair.touchPosition.dx.toInt()}, Y:${keyPair.touchPosition.dy.toInt()}'), if (keyPair.isLongPress) Text(context.i18n.longPress, style: TextStyle(fontSize: 10)), ], + if (keyPair.isLongPress) Text(context.i18n.longPress, style: TextStyle(fontSize: 10)), ], ); } @@ -442,7 +443,7 @@ class _KeyWidget extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 4), constraints: BoxConstraints(minWidth: 30), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.card, + color: BKColor.main, border: Border.all(color: Theme.of(context).colorScheme.border, width: 2), borderRadius: BorderRadius.circular(4), ), diff --git a/lib/utils/keymap/keymap.dart b/lib/utils/keymap/keymap.dart index 6b1966a..8b90847 100644 --- a/lib/utils/keymap/keymap.dart +++ b/lib/utils/keymap/keymap.dart @@ -111,13 +111,14 @@ class KeyPair { IconData? get icon { return switch (physicalKey) { + _ when inGameAction != null && core.logic.emulatorEnabled => Icons.link, + PhysicalKeyboardKey.mediaPlayPause || PhysicalKeyboardKey.mediaStop || PhysicalKeyboardKey.mediaTrackPrevious || PhysicalKeyboardKey.mediaTrackNext || PhysicalKeyboardKey.audioVolumeUp || PhysicalKeyboardKey.audioVolumeDown => Icons.music_note_outlined, - _ when inGameAction != null && touchPosition == Offset.zero && core.logic.emulatorEnabled => Icons.link, _ when physicalKey != null && core.actionHandler.supportedModes.contains(SupportedMode.keyboard) => Icons.keyboard, _ when touchPosition != Offset.zero && core.logic.showLocalRemoteOptions => Icons.touch_app, @@ -231,4 +232,28 @@ class KeyPair { inGameActionValue: decoded['inGameActionValue'], ); } + + @override + bool operator ==(Object other) => + identical(this, other) || + other is KeyPair && + runtimeType == other.runtimeType && + physicalKey == other.physicalKey && + logicalKey == other.logicalKey && + modifiers == other.modifiers && + touchPosition == other.touchPosition && + isLongPress == other.isLongPress && + inGameAction == other.inGameAction && + inGameActionValue == other.inGameActionValue; + + @override + int get hashCode => Object.hash( + physicalKey, + logicalKey, + modifiers, + touchPosition, + isLongPress, + inGameAction, + inGameActionValue, + ); } diff --git a/lib/utils/keymap/manager.dart b/lib/utils/keymap/manager.dart index 37bae8b..17e11c8 100644 --- a/lib/utils/keymap/manager.dart +++ b/lib/utils/keymap/manager.dart @@ -261,6 +261,7 @@ class KeymapManager { touchPosition: pair.touchPosition, inGameAction: pair.inGameAction, inGameActionValue: pair.inGameActionValue, + modifiers: pair.modifiers, ); }); }); diff --git a/lib/widgets/apps/openbikecontrol_mdns_tile.dart b/lib/widgets/apps/openbikecontrol_mdns_tile.dart index 258dff9..b38dd04 100644 --- a/lib/widgets/apps/openbikecontrol_mdns_tile.dart +++ b/lib/widgets/apps/openbikecontrol_mdns_tile.dart @@ -1,8 +1,9 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; +import 'package:swift_control/bluetooth/devices/zwift/protocol/zp.pb.dart'; +import 'package:swift_control/bluetooth/messages/notification.dart'; import 'package:swift_control/utils/core.dart'; import 'package:swift_control/utils/i18n_extension.dart'; import 'package:swift_control/widgets/ui/connection_method.dart'; -import 'package:swift_control/widgets/ui/toast.dart'; class OpenBikeControlMdnsTile extends StatefulWidget { const OpenBikeControlMdnsTile({super.key}); @@ -37,12 +38,15 @@ class _OpenBikeProtocolTileState extends State { } else if (value) { core.obpMdnsEmulator.startServer().catchError((e) { core.settings.setObpMdnsEnabled(false); - buildToast( - context, - title: context.i18n.errorStartingOpenBikeControlServer, + core.connection.signalNotification( + AlertNotification( + LogLevel.LOGLEVEL_ERROR, + context.i18n.errorStartingOpenBikeControlServer, + ), ); }); } + setState(() {}); }, isStarted: isStarted, isConnected: isConnected != null, diff --git a/lib/widgets/keymap_explanation.dart b/lib/widgets/keymap_explanation.dart index e31c986..1b45b8e 100644 --- a/lib/widgets/keymap_explanation.dart +++ b/lib/widgets/keymap_explanation.dart @@ -160,6 +160,17 @@ class _ButtonEditor extends StatelessWidget { ); if (newName != null) { buildToast(context, title: context.i18n.createdNewCustomProfile(newName)); + final selectedKeyPair = core.actionHandler.supportedApp!.keymap.keyPairs.firstWhere( + (e) => e == this.keyPair, + ); + await openDrawer( + context: context, + builder: (c) => ButtonEditPage( + keyPair: selectedKeyPair, + onUpdate: () {}, + ), + position: OverlayPosition.end, + ); } onUpdate(); } else { diff --git a/lib/widgets/ui/button_widget.dart b/lib/widgets/ui/button_widget.dart index 0d7f593..2298f98 100644 --- a/lib/widgets/ui/button_widget.dart +++ b/lib/widgets/ui/button_widget.dart @@ -2,6 +2,7 @@ import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:swift_control/main.dart'; import 'package:swift_control/utils/keymap/buttons.dart'; import 'package:swift_control/widgets/keymap_explanation.dart'; +import 'package:swift_control/widgets/ui/colors.dart'; class ButtonWidget extends StatelessWidget { final ControllerButton button; @@ -23,7 +24,7 @@ class ButtonWidget extends StatelessWidget { ), shape: button.color != null || button.icon != null ? BoxShape.circle : BoxShape.rectangle, borderRadius: button.color != null || button.icon != null ? null : BorderRadius.circular(4), - color: button.color ?? Theme.of(context).colorScheme.card, + color: button.color ?? BKColor.main, ), child: Center( child: button.icon != null @@ -38,7 +39,7 @@ class ButtonWidget extends StatelessWidget { fontFamily: screenshotMode ? null : 'monospace', fontSize: big && button.color != null ? 20 : 12, fontWeight: button.color != null ? FontWeight.bold : null, - color: button.color != null ? Colors.white : Theme.of(context).colorScheme.primaryForeground, + color: button.color != null ? Colors.white : Theme.of(context).colorScheme.foreground, ), ), ),