import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; enum WindowMode { windowed, borderlessFullscreen; String get displayString { switch (this) { case WindowMode.windowed: return "Windowed"; case WindowMode.borderlessFullscreen: return "Borderless Fullscreen"; } } String get pascalCase { switch (this) { case WindowMode.windowed: return "Windowed"; case WindowMode.borderlessFullscreen: return "BorderlessFullscreen"; } } static WindowMode fromPascalCase(String pascalCase) { return WindowMode.values.firstWhere((mode) => mode.pascalCase == pascalCase); } } class ProjectConfig extends ChangeNotifier { final TextEditingController _gameName; final TextEditingController _defaultWindowWidth; final TextEditingController _defaultWindowHeight; bool _defaultVsync; WindowMode _defaultWindowMode; String get gameName => this._gameName.text; set gameName(String gameName) { this._gameName.text = gameName; } int get defaultWindowWidth => int.parse(this._defaultWindowWidth.text); set defaultWindowWidth(int defaultWindowWidth) { this._defaultWindowWidth.text = defaultWindowWidth.toString(); } int get defaultWindowHeight => int.parse(this._defaultWindowHeight.text); set defaultWindowHeight(int? defaultWindowHeight) { this._defaultWindowHeight.text = defaultWindowHeight.toString(); } bool get defaultVsync => this._defaultVsync; set defaultVsync(bool defaultVsync) { this._defaultVsync = defaultVsync; notifyListeners(); } WindowMode get defaultWindowMode => this._defaultWindowMode; set defaultWindowMode(WindowMode defaultWindowMode) { this._defaultWindowMode = defaultWindowMode; notifyListeners(); } ProjectConfig({ String gameName = "Black Screen", int defaultWindowWidth = 1280, int defaultWindowHeight = 720, bool defaultVsync = true, WindowMode defaultWindowMode = WindowMode.windowed, }) : this._gameName = TextEditingController(text: gameName), this._defaultWindowWidth = TextEditingController(text: defaultWindowWidth.toString()), this._defaultWindowHeight = TextEditingController(text: defaultWindowHeight.toString()), this._defaultVsync = defaultVsync, this._defaultWindowMode = defaultWindowMode; } class ProjectPage extends StatelessWidget { const ProjectPage({super.key}); int getWidth(ProjectConfig config) => int.tryParse(config._defaultWindowWidth.text) ?? 1280; int getHeight(ProjectConfig config) => int.tryParse(config._defaultWindowHeight.text) ?? 720; @override Widget build(BuildContext context) { var config = Provider.of(context, listen: false); return Padding( padding: const EdgeInsets.all(20), child: Form( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 600, child: TextFormField( decoration: const InputDecoration( labelText: "Project Name", //helperText: "This will appear as the game window's title", border: OutlineInputBorder(), ), controller: config._gameName, ), ), const SizedBox(height: 20), DropdownMenu( width: 600, label: const Text("Default Window Mode"), initialSelection: config.defaultWindowMode, onSelected: (v) => config.defaultWindowMode = v!, dropdownMenuEntries: WindowMode.values .map(((mode) => DropdownMenuEntry(value: mode, label: mode.displayString))) .toList(), ), const SizedBox(height: 20), Consumer( builder: (context, config, child) => Row( children: [ SizedBox( width: 300, child: TextFormField( decoration: const InputDecoration( labelText: "Default Resolution Width", border: OutlineInputBorder(), ), controller: config._defaultWindowWidth, keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], ), ), ], ), ), const SizedBox(height: 20), Consumer( builder: (context, config, child) => Row( children: [ SizedBox( width: 300, child: TextFormField( decoration: const InputDecoration( labelText: "Default Resolution Height", border: OutlineInputBorder(), ), controller: config._defaultWindowHeight, keyboardType: TextInputType.number, inputFormatters: [FilteringTextInputFormatter.digitsOnly], ), ), ], ), ), const SizedBox(height: 20), SizedBox( width: 250, child: Consumer( builder: (context, config, child) => CheckboxListTile( value: config.defaultVsync, onChanged: (v) => config.defaultVsync = v!, title: const Text("Default Vsync", style: TextStyle(fontSize: 20)), controlAffinity: ListTileControlAffinity.leading, ), ), ), ], ), ), ); } }