feat: Integrate window manager for desktop windowing support and enhance input handling
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
/// Active gameplay screen for the Flutter host.
|
||||
library;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
|
||||
import 'package:wolf_3d_dart/wolf_3d_renderer.dart';
|
||||
import 'package:wolf_3d_flutter/wolf_3d_flutter.dart';
|
||||
import 'package:wolf_3d_flutter/wolf_3d_input_flutter.dart';
|
||||
import 'package:wolf_3d_renderer/wolf_3d_ascii_renderer.dart';
|
||||
import 'package:wolf_3d_renderer/wolf_3d_flutter_renderer.dart';
|
||||
import 'package:wolf_3d_renderer/wolf_3d_glsl_renderer.dart';
|
||||
@@ -16,14 +21,28 @@ enum RendererMode {
|
||||
hardware,
|
||||
}
|
||||
|
||||
typedef HostShortcutHandler =
|
||||
bool Function(
|
||||
KeyEvent event,
|
||||
Wolf3dFlutterInput input,
|
||||
);
|
||||
|
||||
/// Launches a [WolfEngine] via [Wolf3d] and exposes renderer/input integrations.
|
||||
class GameScreen extends StatefulWidget {
|
||||
/// Shared application facade owning the engine, audio, and input.
|
||||
final Wolf3d wolf3d;
|
||||
|
||||
/// Optional host-level shortcut override.
|
||||
///
|
||||
/// Return `true` when the event was consumed. Handlers may call
|
||||
/// [Wolf3dFlutterInput.suppressActionOnce] to keep actions from reaching the
|
||||
/// engine update loop.
|
||||
final HostShortcutHandler? hostShortcutHandler;
|
||||
|
||||
/// Creates a gameplay screen driven by [wolf3d].
|
||||
const GameScreen({
|
||||
required this.wolf3d,
|
||||
this.hostShortcutHandler,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -155,6 +174,10 @@ class _GameScreenState extends State<GameScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_handleHostShortcut(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.logicalKey == widget.wolf3d.input.rendererToggleKey) {
|
||||
setState(_cycleRendererMode);
|
||||
return;
|
||||
@@ -218,4 +241,61 @@ class _GameScreenState extends State<GameScreen> {
|
||||
void _toggleGlslEffects() {
|
||||
_glslEffectsEnabled = !_glslEffectsEnabled;
|
||||
}
|
||||
|
||||
bool _handleHostShortcut(KeyEvent event) {
|
||||
final HostShortcutHandler? customHandler = widget.hostShortcutHandler;
|
||||
if (customHandler != null) {
|
||||
return customHandler(event, widget.wolf3d.input);
|
||||
}
|
||||
|
||||
if (_isAltEnter(event)) {
|
||||
// Consume Enter so fullscreen toggling does not also activate menu items.
|
||||
widget.wolf3d.input.suppressInteractOnce();
|
||||
unawaited(_toggleFullscreen());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _isAltEnter(KeyEvent event) {
|
||||
final bool isEnter =
|
||||
event.logicalKey == LogicalKeyboardKey.enter ||
|
||||
event.logicalKey == LogicalKeyboardKey.numpadEnter;
|
||||
if (!isEnter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Set<LogicalKeyboardKey> pressedKeys =
|
||||
HardwareKeyboard.instance.logicalKeysPressed;
|
||||
return pressedKeys.contains(LogicalKeyboardKey.altLeft) ||
|
||||
pressedKeys.contains(LogicalKeyboardKey.altRight) ||
|
||||
pressedKeys.contains(LogicalKeyboardKey.alt);
|
||||
}
|
||||
|
||||
Future<void> _toggleFullscreen() async {
|
||||
if (!_supportsDesktopWindowing) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final bool isFullScreen = await windowManager.isFullScreen();
|
||||
await windowManager.setFullScreen(!isFullScreen);
|
||||
} on MissingPluginException {
|
||||
// No-op on hosts where the window manager plugin is unavailable.
|
||||
}
|
||||
}
|
||||
|
||||
bool get _supportsDesktopWindowing {
|
||||
if (kIsWeb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return switch (defaultTargetPlatform) {
|
||||
TargetPlatform.linux ||
|
||||
TargetPlatform.windows ||
|
||||
TargetPlatform.macOS => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user