Skip to content

Commit

Permalink
Finish up New Map dialog!
Browse files Browse the repository at this point in the history
  • Loading branch information
TechnicJelle committed Sep 3, 2024
1 parent 8aa2303 commit 7850137
Showing 1 changed file with 87 additions and 41 deletions.
128 changes: 87 additions & 41 deletions lib/new_map_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import "dart:io";
import "dart:math";

import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
Expand All @@ -9,6 +8,8 @@ import "dual_pane.dart";
import "main.dart";
import "utils.dart";

final RegExp regexIDValidation = RegExp(r"^[a-zA-Z0-9_-]+$");

//TODO: Show options dialog
// - map name? (gets turned into a map ID and compared against existing map IDs)
// other options won't be in this initial dialog, but in the actual config screen
Expand All @@ -21,11 +22,16 @@ class NewMapDialog extends ConsumerStatefulWidget {
}

class _NewMapDialogState extends ConsumerState<NewMapDialog> {
//Widget stuff
final formKey = GlobalKey<FormState>();
final idController = TextEditingController();

//Data stuff
late final List<DropdownMenuEntry<File>> options;
late final Directory projectDirectory;

//Output stuff
File? selectedTemplate;
String? templateError;

@override
void initState() {
Expand All @@ -51,29 +57,88 @@ class _NewMapDialogState extends ConsumerState<NewMapDialog> {
.toList();
}

void validateAndCreate() {
final formState = formKey.currentState;
if (formState != null && formState.validate()) {
File template = selectedTemplate!;
String id = idController.text;

File newConfig = File(
p.join(projectDirectory.path, "config", "maps", "$id.conf"),
);

template.copySync(newConfig.path);

Navigator.of(context).pop();

ref.read(openConfigProvider.notifier).open(newConfig);
}
}

@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text("New map"),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
const Text("Map type:"),
const SizedBox(height: 8),
DropdownMenu(
hintText: "Select a template",
errorText: templateError,
dropdownMenuEntries: options,
onSelected: (File? template) {
setState(() {
selectedTemplate = template;
templateError = null;
});
},
width: 200,
),
],
content: Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
const Text("Map type:"),
const SizedBox(height: 8),
FormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (field) {
if (selectedTemplate == null) {
return "Can't be empty";
}
return null;
},
builder: (field) => DropdownMenu(
hintText: "Select a template",
errorText: field.errorText,
dropdownMenuEntries: options,
onSelected: (File? template) {
setState(() {
selectedTemplate = template;
field.didChange(template);
});
},
width: 200,
),
),
const SizedBox(height: 16),
const Text("Map ID:"),
TextFormField(
controller: idController,
decoration: InputDecoration(
hintText: selectedTemplate == null
? "my-cool-map"
: "my-cool-${p.basenameWithoutExtension(selectedTemplate!.path)}-map",
),
textInputAction: TextInputAction.done,
textCapitalization: TextCapitalization.none,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (String? s) {
if (s == null || s.trim().isEmpty) {
return "Can't be empty";
}
if (!regexIDValidation.hasMatch(s)) {
return "Invalid character";
}
File potentialNewConfig = File(
p.join(projectDirectory.path, "config", "maps", "$s.conf"),
);
if (potentialNewConfig.existsSync()) {
return "Can't have a duplicate ID";
}
return null;
},
onFieldSubmitted: (_) => validateAndCreate(),
),
],
),
),
actions: [
TextButton(
Expand All @@ -83,26 +148,7 @@ class _NewMapDialogState extends ConsumerState<NewMapDialog> {
child: const Text("Cancel"),
),
ElevatedButton(
onPressed: () {
File? template = selectedTemplate;
if (template == null) {
setState(() {
templateError = "Please select a template";
});
return;
}

File newConfig = File(
p.join(projectDirectory.path, "config", "maps",
"new-map-${Random().nextInt(999)}.conf"),
);

template.copySync(newConfig.path);

Navigator.of(context).pop();

ref.read(openConfigProvider.notifier).open(newConfig);
},
onPressed: () => validateAndCreate(),
child: const Text("Create"),
),
],
Expand Down

0 comments on commit 7850137

Please sign in to comment.